Divise + Omniauth2.0

Nowadays, OAuth2 is quite popular. We are not going too in-depth on how it’s work. We will develop an application which will use devise and omniauth2 so, our application will have a feature of signup using Omniauth or devise.

Step 1: Create Account at Provider i.e. google

I am taking Google as an example. or a full list of these providers, please check OmniAuth’s list of strategies. Go to google developer console and register our application. Google will authorise it next time when it will ask authentications using google. Click on create “OAuth consent screen” link and fill in the required information. After saving go to “Credentials” link and click on “Create credentials”. It will have several options. Click on “OAuth client id”. Follow the instructions and you will have “Client ID” and “Client secretes” at the end. It will require while configuring devise.

Step 2: Install the necessary gems.

Few gems will be needed to implement this feature. Let's add these to our Gemfile and run the command to install them.

  • gem ‘devise’
  • gem ‘devise-bootstrap-views’
  • gem ‘omniauth’
  • gem ‘omniauth-google-oauth2’

Step 3: Setup Devise

I am assuming that we know how to set up devise for authentication in a rails app. Follow this to see how to set up devise.

Step 4: Integrate Omniauth2 with devise

For this, we need to update our users table. We need to add the columns “provider” (string) and “uid” (string) to your User model.

rails g migration AddOmniauthToUsers provider:string uid:string
rake db:migrate

NOTE: we are using Omniauth with devise hence no need to add provider middleware again in config/initializers/omniauth.rb

Now, declare the provider in your config/initializers/devise.rb.

config.omniauth :google_oauth2, "Client_ID", "Client_Secret", "callback_url"

Client_ID, Client_Secret and callback_url are generated in step1. callback_url may look like http://localhost:3000/users/auth/google_oauth2/callback.

This will configure our strategy, we need to make our model (e.g. app/models/user.rb) omniauthable:

devise :omniauthable, :omniauth_providers => [:google_oauth2]

we can add multiple providers. Now devise is already set up so it will create the following URL methods:

  • user_omniauth_authorize_path(provider)
  • user_omniauth_callback_path(provider)

we can use this path methods to generate sign in link i.e.

<%= link_to “Sign in with Google+”, user_google_oauth2_omniauth_authorize_path %>

By clicking on the above link, the user will be redirected to Google. (If this link doesn’t exist, try restarting the server.) After inserting their credentials, they will be redirected back to your application’s callback method. To implement a callback, the first step is to go back to our config/routes.rb file and tell Devise in which controller we will implement Omniauth callbacks:

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

Now add the file app/controllers/users/omniauth_callbacks_controller.rb and implemented callback as an action with the same name as the provider. Here is an example action for our google provider that we could add to our controller:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
@user = User.from_omniauth(request.env["omniauth.auth"])

if @user.persisted?
sign_in_and_redirect @user, :event => :authentication
set_flash_message(:notice, :success, :kind => "Google") if is_navigational_format?
else
session["devise.data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end

def failure
redirect_to root_path
end
end

Here, all information retrieved from Google by OmniAuth is available as a hash at request.env[“omniauth.auth”]. Now, Implement a method to our user model.

def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name # assuming the user model has a name
user.image = auth.info.image # assuming the user model has an image
# If you are using confirmable and the provider(s) you use validate emails,
# uncomment the line below to skip the confirmation emails.
# user.skip_confirmation!
end
end

This method tries to find an existing user by the provider and uid fields. If no user is found, a new one is created with a random password and some extra information.

Finally, if you want to allow your users to cancel sign up with Google, you can redirect them to cancel_user_registration_path. This will remove all session data starting with devise. and the new_with_session hook above will no longer be called.

Step 5: Logout links

devise_for :users, :controllers => {
:omniauth_callbacks => "users/omniauth_callbacks" } do
delete 'sign_out', :to => 'devise/sessions#destroy',
:as => :destroy_user_session
end

You can find code here on GitHub

If you have queries then I will happy to help you out. Please reach me out at mayurt20@gmail.com.

Written by

helping companies to take the stress out of software development and make their business shine.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store