Home / Community
Home / Community

Authentications with Omniauth

0db484da0a364dbadf287398f97a97dbby Nora Alvarado|

May 01, 2012


Having a site that allows you to authenticate using a third-party service, such as Facebook, Twitter or Google, turns out to be very handy these days. One easy way to handle the authorizations in your Rails app is with the Omniauth Gem.

Omniauth allows you to integrate one or more of these providers (also called strategies) in your app. So after reading and reviewing some Omniauth articles, I decided to put the most relevant info in this post. In it, I´ll guide you on how to implement it in a Rails App using the Github and Twitter providers.

  1. Add the gem according with the provider you choose:


    gem 'omniauth-github'
    gem 'omniauth-twitter'
  2. Create an application with your provider:

    For Github go to: http://github.com/account/applications, fill the form and click 'Create Application'

    Form image

    While your are on development, you can setup the URL and Callback URL to point at your local host as follows:

    Url: http://localhost:3000
    Callback URL: http://localhost:3000/auth/github/callback

    To create a Twitter application go to: https://dev.twitter.com/apps/new

    When you create a Twitter application, it doesn't allow you to set your url and your callback url to your localhost (due to security issues), but there are a few workarounds that you can do to test your app on your localhost:

    a) Take your localhost url i.e. http://localhost:3000/auth/twitter/callback and use a shortening service like http://goo.gl/, and point your application to that url, you'll have something like this: http://goo.gl/dH7Md

    b) Set your application callback to

    c) Use pow to run your app, and then use the url like i.e http://myapp.dev/auth/twitter/callback

    Once Finished, your twitter set up should look something like this:

    Form image

    Remember to change URL and Callback URL when going to production.

  3. Once you have your providers apps all set up, create an Omniauth initializer file, you will need the Client ID and Secret keys from the Github application, and the Consumer Key and Consumer Secret from your Twitter application:


        ENV['GITHUB_KEY'] ||= 'Client ID'
        ENV['GITHUB_SECRET'] ||= 'Secret'
        ENV['TWITTER_KEY'] ||= 'Consumer Key'
        ENV['TWITTER_SECRET'] ||= 'Consumer Secret'  
        Rails.application.config.middleware.use OmniAuth::Builder do  
          provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']  
          provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']  
  4. Add needed routes for your authentications:


        match "/auth/:provider/callback" => "sessions#create"  
        match '/auth/failure', :to => 'sessions#failure'  
        match "/signout" => "sessions#destroy", :as => :signout  
  5. The next thing that we are going to need, if you don't have one yet, is to set up a controller to manage your sessions:


        class SessionsController < ApplicationController  
          def create
            if session[:id]
              auth = Authorization.find_or_create_by_provider(auth_hash)  
              session[:id] = auth.user_id   
            redirect_to '/', :notice => "Signed in!"  
          def destroy
            session[:id] = nil
            redirect_to root_url, :notice => "Signed out!"
          def failure
            redirect_to '/', :alert => 'Sorry, something went wrong. Try again.'
          def auth_hash
  6. Now are going to need a couple of models, a User model and Authorization model. If you dont have those models yet, is time to create them! Keep in mind that we are going to need at least the following attributes:

    User Model

        name: string
        email: string

    Authorization Model

        provider: string
        uid: string

    Check the link to the Hash Schema at the end of this post to see all the aviable attributes

    In our User model, add the create_provider method (called in the create action of our sessions controller) along with the user data hash that we need to save:

        class User < ActiveRecord::Base
          has_many :authorizations
          def create_provider(auth_hash)
            unless authorizations.find_by_provider_and_uid(auth_hash["provider"],  
              Authorization.create( :user => current_user,  
                    :provider => auth_hash["provider"], 
                    :uid => auth_hash["uid"] )

    In our Authorization model, we need the find_or_create_by_provider method:

       class Authorization < ActiveRecord::Base
         belongs_to :user
         validates :provider, :uid, presence: true
         def self.find_or_create_by_provider(auth_hash)
           unless auth = find_by_provider_and_uid(auth_hash['provider'],  
             user = User.create(name: auth_hash['info']['name'],  
                            email: auth_hash['info']['email'])  
             auth = create user:( user, provider: auth_hash['provider'],  
                            uid: auth_hash['uid'] )  
  7. We are going to need a few methods in our application controller, define three helper_methods, one to find the current user by its session id and one method that redirects to the root path if the user hasn't been authenticated yet. Also we need to add a before_filter that checks the callback url when our app is in production to avoid callback errors.

       class ApplicationController < ActionController::Base
         before_filter :check_uri
         helper_method :current_user, :authenticate_user!  
         def check_uri
           url = redirect_to request.protocol + 'www.' + request.host_with_port + 
                 request.fullpath if Rails.env.to_s == 'production' &&   
                 !/^www/.match(request.host) && ENV['DEV'].nil?
         def current_user
           @current_user ||= User.find_by_id(session[:id])
         def authenticate_user!
           if session[:id]
             redirect_to '/'
  8. At last, but not least, configure the view where you want the login links, it might be something like this:

    If the user is not logged in

       %h2 Welcome to the Omniauth Example... Login with your preferred provider!
       = link_to image_tag('github.png'), '/auth/github' 
       = link_to image_tag('twitter.png'), '/auth/twitter'  

    if the user is logged in

         You are logged in as #{current_user.name}
         = link_to 'Logout', '/signout'


As you can see, implementing Omniauth is pretty straight foward. I hope you found this post helpful. You can also take a look at the example app in Github

Usefull Links:

blog comments powered byDisqus