Codementor Events

Rails. Omniauth with devise (github example)

Published Feb 04, 2015Last updated Feb 15, 2017

What We Aim To Do?

Create simple app with Auth handling by third part provider, in our case it will be github .

What is Omniauth?

OmniAuth is a library that standardizes multi-provider authentication for web applications. It also contains specifications for passing data to/from provider.

Let's start!

First of all we create rails app

rails new git_omni

add gem 'devise' to your Gemfile and install it

bundle install
rails g devise:install

after that we have to create user model

rails g devise user
bundle exec rake db:migrate

Ok, we are all set with devise, let's jump to omniauth.

How it works?

There are basic steps for user handling by Auth with Omniauth:

  1. User click on 'auth with github'
  2. Rails app redirect him to github page
  3. User sign in on github and grant access to your app
  4. Github redirect user back to your rails app
  5. Rails app got at least two things: provider and uid
  6. Now we can use this info to sign in user in app

In conclusion, we use provider and uid returned from github to sign in/register user in our app.

Go Over Omniauth

All instructions below related to github provider, but you can use anyone. All available strategies with gems located there.

we will use gem 'omniauth-github' and run bundle install

Add Routes and Controller

As you remember, after success signing in provider will redirect user to some url in our page. We should create route for that and handle them in controller

Add omniauth callbacks to config/routes.rb

devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }

and create new controller for handle callback app/controllers/callbacks_controller.rb

class CallbacksController < Devise::OmniauthCallbacksController
  def github
    @user = User.from_omniauth(request.env["omniauth.auth"])
    sign_in_and_redirect @user
  end
end

Ok, now we've got provider and uid from github, but what about from_omniauth method? Let's implement them!

Add Support Omniauth to Your Model

Add uid and provider fields to users table

rails g migration AddColumnsToUsers provider uid
bundle exec rake db:migrate

Add omniauthable module and from_omniauth class method to the model

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable

  def self.from_omniauth(auth)  
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]
    end
  end
end

Ok, we're done with coding. Now we need to create app on provider side and set devise config.

Create Github App

https://github.com/settings/applications/new

Set site url to http://localhost:3000/ and callback url to http://localhost:3000/users/auth/github/callback

When we done, go to the config/initializers/devise.rb and add omiauth config (paste your client ID and secret instead of placeholders)

 config.omniauth :github, 'CLIENT_ID', 'APP_SECRET', :scope => 'user:email'

Well done! Restart server and go to "/users/sign_in", you will see link for github sign in.

You can see working solution on github.

Will appreciate any comments, questions and suggestions!

Discover and read more posts from Alexey Naumov
get started
post comments10Replies
Zhu Jiang
6 years ago

thanks you man

Alexey Naumov
6 years ago

Welcome! I hope it’s not very outdated now :)

BKSpurgeon
7 years ago

Hi there. thanks for this post. how will the above handle refresh tokens?

Steve Brewer
8 years ago

This is giving me a Github 404 page not found error when I try to sign up with Github. This is the URL I’m being sent to:

https://github.com/login/oa…

Steve Brewer
8 years ago

It wasn’t putting my client ID into the URL. I added it to the URL manually and that works. I can’t figure out why Rails isn’t adding the ID to the URL though.

ALI AHMAD
4 years ago

did you solve it?

Show more replies