What\'s the best way to enable users to log in with their email address OR their username? I am using warden + devise for authentication. I think it probably won\'t be too h
From their Wiki — How To: Allow users to sign in using their username or email address.
https://gist.github.com/867932 : One solution for everything. Sign in, forgot password, confirmation, unlock instructions.
Make sure you already added username field and add username to attr_accessible. Create a login virtual attribute in Users
1) Add login as an attr_accessor
# Virtual attribute for authenticating by either username or email
# This is in addition to a real persisted field like 'username'
attr_accessor :login
2) Add login to attr_accessible
attr_accessible :login
Tell Devise to use :login in the authentication_keys
Modify config/initializers/devise.rb to have:
config.authentication_keys = [ :login ]
Overwrite Devise’s find_for_database_authentication method in Users
# Overrides the devise method find_for_authentication
# Allow users to Sign In using their username or email address
def self.find_for_authentication(conditions)
login = conditions.delete(:login)
where(conditions).where(["username = :value OR email = :value", { :value => login }]).first
end
Update your views Make sure you have the Devise views in your project so that you can customize them
remove <%= f.label :email %> remove <%= f.email_field :email %> add <%= f.label :login %> add <%= f.text_field :login %>
Platforma Tec (devise author) has posted a solution to their github wiki which uses an underlying Warden authentication strategy rather than plugging into the Controller:
https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address
(An earlier answer had a broken link, which I believe was intended to link to this resource.)
def self.find_for_authentication(conditions)
conditions = ["username = ? or email = ?", conditions[authentication_keys.first], conditions[authentication_keys.first]]
# raise StandardError, conditions.inspect
super
end
Use their example!