I'm trying to create a login using devise with a username that I've computed. As an example, let's assume we want to namespace our usernames - and I want to receive a username from the login form, and use namespaced_username to do the actual authentication.
So in my User::SessionsController#create
, I might have:
def create
params[:user][:namespaced_username] = "namespace/#{params[:user][:mobile_number]}"
super
end
Even though devise is listening for namespaced_username (configured with authentication_keys in either initializers or the model itself), and with a user setup as namespace/username
, I still get told Invalid Namespaced username or password is not valid
How can I get devise (the warden strategies, specifically) to read the new param?
It turns out this is a Rails 5 problem. Basically, Warden (which is used by devise) is handed the request object, probably in middleware, and then the controller is handed a copy of the request's params hash.
The easy way to fix it is, within User::SessionsController#create
, we need to add a line:
def create
# Here we change params - but this won't be seen by the warden strategy
params[:user][:namespaced_username] = = "namespace/#{params[:user][:mobile_number]}"
# Inject our changes into the copy in request
request.params[:user].merge!(params[:user])
# now our changes will be seen by warden - continue with devise:
super
end