by
back

login devise users via token

Devise is a powerful user authentication gem for ruby on rails. Usually a user authenticates himself with his email address and a password. To enable the login via a token, you can follow the next steps:

app/models/user.rb

class User < ActiveRecord::Base

    # some other stuff here

    before_save :create_token

    def create_token
        self.token = generate_token if token.blank?
    end

    private

        def generate_token
            loop do
                token = Devise.friendly_token
                break token unless User.where(token: token).first
            end
        end
end

This code will add a token to every new created user. Of course you will need to add the database field "token" to your users table:
rails g migration add_token_to_users token

To ensure that every already user that already existed in your database get's a unique token, you can use the following rake-job:

lib/tasks/users.rake

namespace :users do
    desc "Generate user tokens"
    task :generate_tokens => :environment do
        User.all.each do |user|
            if user.token.blank?
                loop do
                    user.token = Devise.friendly_token
                    break token unless User.where(token: token).first
                end
                user.save
            end
        end
    end 
end

A capistrano recepie for that task could look like

lib/capistrano/tasks/users.cap

namespace :users do
    desc "Generate user tokens"
    task :generate_tokens do
        on roles(:app) do
            warn "\n\n=== generating tokens ===\n\n"
            execute "cd #{current_path}; bundle exec rake users:generate_tokens RAILS_ENV=#{fetch(:stage)}"
        end
    end
end

To use you new generated tokens for a login, we need a route and a controller:

config/routes.rb

get "login/:token" => "pages#token_login"

app/controllers/pages_controller.rb

class PagesController < ApplicationController
    def token_login
        user = User.find_by(token: params[:token])

        if user
            sign_in user
            return redirect_to root_path, notice: "Welcome"
        else
            return redirect_to root_path, alert: "User not found"
        end
    end
end

Of course this way to authenticate users is not very safe, but sometimes it is suitable for your project to enable this sort of token-login.



comments powered by Disqus