breaking into the unknown…

devise login with authentication_token

1 Comment

Devise is a great gem to manage user authentication. You can also authenticate a user i,e make user to login with authentication token. By default token_authentication is inactive for devise but you can activate it with few changes. Devise provide different support for token authentication like creating tokens, validating with passed token, expiring the token etc. The detail list of methods is documented here. I will just list here the changes which will make you existing devise authentication to support token based authentication. I am assuming that the model you are authenticating with devise is User. I will underline any modification we made to existing code

STEP 1:  Add authentication_token field to user model

If you see Your user migration, you will find different devise introduced fields. many of the field which is not needed by default is commented out. Below is the default migration generated by devise for user

class DeviseCreateUsers < ActiveRecord::Migration   def change     create_table(:users) do |t|       ## Database authenticatable       t.string :email,              :null => false, :default => ""
      t.string :encrypted_password, :null => false, :default => ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, :default => 0
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at

      ## Token authenticatable
      # t.string :authentication_token


    add_index :users, :email,                :unique => true
    add_index :users, :reset_password_token, :unique => true
    # add_index :users, :confirmation_token,   :unique => true
    # add_index :users, :unlock_token,         :unique => true
    # add_index :users, :authentication_token, :unique => true

So you can see that field needed for Confirmable,  Lockable and  Token authenticatable module of devise is commented out as they are not the default. whenever you want to activate any module you need to add those fields to the users table. You can see that for authenticable module we need one field and then add index to that. So we will define a new migration and add the required field

class AddAuthenticationTokenToUser < ActiveRecord::Migration   
  def change     
    add_column :users, :authentication_token, :string     
    add_index  :users, :authentication_token, :unique => true

run the migration to introduce the newly added filed rake db:migrate

STEP 2: Modifying the routes.rb for devise

Since, authentication_token concept is basically use to authenticate user from outside i,e say you sent user a email containing the activation link containing the token, so when he click the link he directly get loged in. Similarly, If a User want to access your site from some other site he can access it by authenticating himself by passing proper token in signin url. We need to tell Devise what will be the name of the key which will hold the authentication_key let us call it authentication_key itself

devise_for :users, :token_authentication_key => 'authentication_key'

STEP 3: Modifying the model

In model we will do below modification

class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable,
    :validatable, :timeoutable, :omniauthable , :token_authenticatable # the underline is 
    added to existing code, it will activate authenticable module of Devise

  before_save :ensure_authentication_token # whenever a user is saved i,e created or updated it
  will see that a unique authentication token get created if not already exist


STEP 4: Modifying the Application controller

Now we are ready to go, Devise will take care of everything. It provide a empty method after_token_authentication as hook in which we will do our stuff if the user is authenticated. So we will set a before_filter on this method.

class ApplicationController < ActionController::Base

  before_filter :after_token_authentication # it is empty hook provided by devise i,e 
  once user is successfully authenticated with the token devise look for this method , 
  and execute the code there

  def after_token_authentication
    if params[:authentication_key].present?
      @user = User.find_by_authentication_token(params[:authentication_key]) # we are finding 
      the user with the authentication_key with which devise has authenticated the user
      sign_in @user if @user # we are siging in user if it exist. sign_in is devise method 
                               to sigin in any user
      redirect_to root_path # now we are redirecting the user to root_path i,e our home page


STEP 5: See it working.

Let ,My application is, one of the user have the  authentication token “xyz1234rst” , when he will type below url in browser, he will get loged in and redirected to root_path authentication_key=xyz1234rst

The user is at the home page of the Site…So great….Its working🙂

Author: arunyadav4u

over 7 years experience in web development with Ruby on Rails.Involved in all stage of development lifecycle : requirement gathering, planing, coding, deployment & Knowledge transfer. I can adept to any situation, mixup very easily with people & can be a great friend.

One thought on “devise login with authentication_token

  1. Pingback: In which cases do you need to implement these complex token authentication on devise (Rails 3.2) | Technology & Programming

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s