-
Notifications
You must be signed in to change notification settings - Fork 5.5k
How To: Allow users to sign in with something other than their email address
If you don’t want to use email as a default field for sign in, you can specify another. We will use :username
as the field name in these examples, but you can use any field.
To implement this, uncomment the following text in config/initializers/devise.rb
file and specify the field you want to use during sign in, such as :username
:
config.authentication_keys = [:username]
Another way is to change your model:
devise :database_authenticatable, :authentication_keys => [:username]
Then, add validations to your model:
validates :email, uniqueness: true
validates :username, uniqueness: true
Then, create a migration and migrate:
rails generate migration add_username_to_users username:string:uniq
rake db:migrate
Next, make sure you can set that field when you create and edit users. When using the strong parameters feature in newer versions of Rails, permit reading of that parameter in the controller with .permit(:username)
. Or if you’re using an older version of Rails, make the field accessible in your model with attr_accessible :username
instead.
After this you can generate Devise views using the following command:
rails generate devise:views
And then you’ll need to modify the views in app/views/devise/sessions/new.html.erb
and app/views/devise/registrations/new.html.erb
to use the new form field.
Finally, you might need to change the error message that gets shown to the users if they provide incorrect credentials or when they are not found. You do this in config/locales/devise.en.yml
. Look for the following:
invalid: 'Invalid email or password.'
not_found_in_database: 'Invalid email or password.'
and change it to this:
invalid: 'Invalid username or password.'
not_found_in_database: 'Invalid username or password.'
If you see
invalid: "Invalid %{authentication_keys} or password."
not_found_in_database: "Invalid %{authentication_keys} or password."
instead, you don’t need to change anything.
Note that if you aren’t using e-mail as your authentication key, then it may be the case that users can have multiple accounts with the same e-mail address. This will cause the “recoverable” module not to work well, as it will only include a link in the password reset e-mail to the first account for which it finds a matching e-mail. Here is a thread on the Google Group about how to implement adding all the accounts information into the password reset email.
Important note: If you use validatable
module, define email_required?
and email_changed?
:
# app/models/model.rb
class Model < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:trackable, :lockable, :validatable
def email_required?
false
end
def email_changed?
false
end
# use this instead of email_changed? for Rails = 5.1.x
def will_save_change_to_email?
false
end
end