Rails. Omniauth with devise (github example)
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:
- User click on 'auth with github'
- Rails app redirect him to github page
- User sign in on github and grant access to your app
- Github redirect user back to your rails app
- Rails app got at least two things:
provider
anduid
- 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!
thanks you man
Welcome! I hope it’s not very outdated now :)
Hi there. thanks for this post. how will the above handle refresh tokens?
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…
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.
did you solve it?