rails
(5,290 views)

Login with your email address

Modifications to restful_authentication plug which allows users to log in using their 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/)

 

Comments

by Ben on Sep 22, 2007

>>

Hey great, just what i was after, going to try it out now.

by mary lawson on Sep 20, 2008

Re: Login with your email address

that mite be the only way i can get started. thank you mary ann lawson

by Jon on Jan 04, 2009

>>

Thanks very much!

by thenetduck on Mar 19, 2009

You are a god among ant's

This was very helpful I now worship you...

New Comment

markdown formatting permitted