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 end 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 end end
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 end end
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 end
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 end end end
STEP 5: See it working.
Let ,My application is my_app.com, 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
The user is at the home page of the Site…So great….Its working 🙂