(first posted: Aug 20, 2007)
(2629 Reads)
keywords: restful authentication
Permalink
Login with your email address
The restful_authentication plugin (as well as acts_as_authenticated) setup a user registration with login name, password, email adress, etc. And then prompt the user to log in using the login name and password.
I prefer to let people use just their email address (and password) for logging in rather than login name.
Log in with login name or email
Assuming you still require the user to register a login name, but want to let them log in with either the login name or email address, the change is simple. Edit the models/users.rb file and add the following line to self.authenticate method:
def self.authenticate(login, password)
u = find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login] # need to get the salt
u ||= find :first, :conditions => ['email = ? and activated_at IS NOT NULL', login]
u && u.authenticated?(password) ? u : nil
end
Then you can change views/sessions/_new.rthml to prompt for "Login name or email address"
Use email only (eliminate login name)
Actually, I prefer to let users register with just their email address and a password, and not even bother with a login name.
(However, I do require the provide their full name, which is used for display purposes when I dont want to disclose their email to other users).
Here's the changes needed to implement:
First, edit the models/users.rb file as follows:
- remove validates_presence_of :login
- remove validates_length_of :login
- remove validates_uniqueness_of :login
in self.authenticate method , replace
#u = find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login] # need to get the salt
u = find :first, :conditions => ['email = ? and activated_at IS NOT NULL', login]
in encrypt_password method, replace
#self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{email}--") if new_record?Next, edit controllers/users_controller.rb as follows:
in change_password method, replace
#if User.authenticate(current_user.login, params[:old_password])
if User.authenticate(current_user.email, params[:old_password])
As for the views, modify the views removing any reference to the :login field as follows:
login.rhtml : change prompt for "Email" (Note, I've kept the field name "login" in the form so that the sessions_controller doesnt need to change)
<p><label for="login">Your Email</label><br/>
<%%= text_field_tag 'login' %></p>
signup.rhtml : remove label and field for :login
signup_notification.rhtml : remove
Username: <%%= @<%= file_name %>.login %>
Finally, it would be prudent to update the tests. In file test/functional/sessions_controller_test.rb, change login to pass email rather than login name in several places as follows:
post :create, :login => 'quentin@example.com', :password => 'test'
Optionally you could also remove the login value from the fixtures (users.yml), or even create a migration that removes the login column from the users table altogether.
Email Confirmation
A bit of candy, I also added an email_confirmation field to the registration form. To handle this, I added to models/user.rb
acts_as_modified
validates_presence_of :email_confirmation, :if => :email_modified?
validates_confirmation_of :email, :if => :email_modified?
The :email_modified? method is provided by acts_as_modified plugin (http://svn.viney.net.nz/things/rails/plugins/acts_as_modified/)




Login with your email address
Posted by: Ben on September 22, 2007 03:16 PM#