Forked from gonzalo-bulnes/XXXXXXXXXXXXX_add_authentication_token_to_users.rb
Created
February 14, 2014 10:39
-
-
Save etrepat/8999052 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/application_controller.rb | |
# This application controller was extracted from a Rails-API application, | |
# the only line related to token authentication is the concern inclusion. | |
# | |
# The same line can be added to a regular Rails controller (which inherits from ActionController::Base). | |
# | |
# See https://github.com/rails-api/rails-api for details about Rails-API. | |
class ApplicationController < ActionController::API | |
include ActionController::MimeResponds | |
include ActionController::ImplicitRender | |
# Concerns | |
include TokenAuthentication | |
respond_to :html, :xml, :json | |
end | |
# Example: | |
# | |
# class ApplicationController < ActionController::Base | |
# | |
# # Concerns | |
# include TokenAuthentication | |
# | |
# respond_to :html, :xml, :json | |
# end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/concerns/token_authenticable.rb | |
module TokenAuthenticable | |
extend ActiveSupport::Concern | |
# Please see https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 | |
# before editing this file, the discussion is very interesting. | |
included do | |
private :generate_authentication_token | |
before_save :ensure_authentication_token | |
end | |
def ensure_authentication_token | |
if authentication_token.blank? | |
self.authentication_token = generate_authentication_token | |
end | |
end | |
def generate_authentication_token | |
loop do | |
token = Devise.friendly_token | |
break token unless User.where(authentication_token: token).first | |
end | |
end | |
module ClassMethods | |
# nop | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/concerns/token_authentication.rb | |
module TokenAuthentication | |
extend ActiveSupport::Concern | |
# Please see https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 | |
# before editing this file, the discussion is very interesting. | |
included do | |
private :authenticate_user_from_token! | |
# This is our new function that comes before Devise's one | |
before_filter :authenticate_user_from_token! | |
# This is Devise's authentication | |
before_filter :authenticate_user! | |
end | |
# For this example, we are simply using token authentication | |
# via parameters. However, anyone could use Rails's token | |
# authentication features to get the token from a header. | |
def authenticate_user_from_token! | |
# Set the authentication params if not already present | |
if user_token = params[:user_token].blank? && request.headers["X-User-Token"] | |
params[:user_token] = user_token | |
end | |
if user_email = params[:user_email].blank? && request.headers["X-User-Email"] | |
params[:user_email] = user_email | |
end | |
user_email = params[:user_email].presence | |
user = user_email && User.find_by(email: user_email) | |
# Notice how we use Devise.secure_compare to compare the token | |
# in the database with the token given in the params, mitigating | |
# timing attacks. | |
if user && Devise.secure_compare(user.authentication_token, params[:user_token]) | |
# Notice we are passing store false, so the user is not | |
# actually stored in the session and a token is needed | |
# for every request. If you want the token to work as a | |
# sign in token, you can simply remove store: false. | |
sign_in user, store: false | |
end | |
end | |
module ClassMethods | |
# nop | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
class User < ActiveRecord::Base | |
# Concerns | |
include TokenAuthenticable | |
# Use any Devise module you want! | |
# Include some (non-default) devise modules. Others available are: | |
# :database_authenticatable, :registerable, | |
# :recoverable, :rememberable, :trackable, :validatable | |
# :confirmable, :lockable and :timeoutable | |
devise :omniauthable, :omniauth_providers => [:open_id] | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# spec/models/user_spec.rb | |
require 'spec_helper' | |
describe User do | |
# attributes | |
# ... | |
it { expect(subject).to respond_to :authentication_token } # Token authentication | |
# methods | |
# ... | |
describe "#ensure_authentication_token" do # Token authentication | |
context "when the user has no authentication token" do | |
subject(:user_created_without_auth_token) { FactoryGirl.create(:user) } | |
it "creates one" do | |
expect(subject.authentication_token).not_to be_blank | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# db/migrate/XXXXXXXXXXXXX_add_authentication_token_to_users.rb | |
class AddAuthenticationTokenToUsers < ActiveRecord::Migration | |
def change | |
add_column :users, :authentication_token, :string | |
add_index :users, :authentication_token, :unique => true | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment