Monday, September 05, 2011

Using email or nickname to log in using authlogic and Rails 3

This is a continuation of my first authlogic/Rails 3 post.

Authlogic users have both "login" and "email" properties by default. I wanted to allow users to log in via their email address or nickname. I tackled this in two steps. First, switch to logging in using the "email" property. Second, create a "nickname" property, and allow users to log in with either one. (Yes, I actually wanted to call it "nickname"; I probably could have just aliased it or something.)

In addition to the column-dropping migration, I needed to change the authlogic config to use the "email" property for user lookup, and to not validate the "login" property, since it no longer existed. This is handled in the acts_as_authentic configuration as discussed previously.
  acts_as_authentic do |c|
    c.login_field = :email
    c.validate_login_field = false
    c.require_password_confirmation = false
  end

Lines two and three do what we expect. These configuration fields are documented in the login field configuration section of the authlogic docs. Part the first, done.

If we want to allow users to log in by either email or nickname we need to change both the user and user session classes (in addition to adding the "nickname" property to our user model, of course).

First we add a user class method to look up users by nickname or email.
class User < ActiveRecord::Base
  # acts_as_authentic config removed for clarity.
  class << self
    def find_by_nickname_or_email(s)
      find_by_nickname(s) || find_by_email(s)
    end
  end
end

In the user session class we'll define the user lookup method. While we're here, we'll genericize the error message to something not tied to property names.
class UserSession < Authlogic::Session::Base
  # Use authlogic's default message
  # generalize_credentials_error_messages true
  # Use our own message
  generalize_credentials_error_messages "Login info is invalid!"
  find_by_login_method :find_by_nickname_or_email
end

This is documented in the session configuration section of the authlogic docs.

Users can now log in using either their email, or their nickname. As it stands, the sample app doesn't do much to enforce uniqueness (other than the authlogic defaults) of emails or nicknames.

(It also seems like we should disallow using someone else's email as a nickname, perhaps disallow emails-as-nicknames altogether.)

No comments: