In this post I’ll explain how to integrate google omniauth with Devise in Rails.

Step 1: Add Gems to Gemfile
# Gemfile:

gem 'devise'
gem 'omniauth'
gem 'omniauth-google-oauth2'

# Run bundle to install the gems
$ bundle install
Step 2: Add Column for Omniauth & UID
$ rails g migration AddOmniauthToUsers omniauth:string uid:string

# Then run migration
$ rake db:migrate
Step 3: Go to the User model and add the :omniauthable module
# app/model/user.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :recoverable,
         :rememberable, :trackable, :validatable, :omniauthable
end
Step 4: Create a Project in google to get “Client key” and “Client Secret key”

https://console.developers.google.com/

Step 5: Modify the devise initializers and add this block around line 240
# config/initializers/devise.rb

require 'omniauth-google-oauth2'
config.omniauth :google_oauth2,
  "APP_ID",
  "APP_SECRET",
  { access_type: "offline", approval_prompt: "" }

# Add hd: if want users login only for specific domain:
# Ex. { access_type: "offline", approval_prompt: "", hd: "vertilux.com" }
Step 6: Modify devise login block and routes.rb and add the folowing lines
# app/views/devise/registrations/new.html.erb
<%= link_to "Sign in with Google", user_omniauth_authorize_path(:google_oauth2) %>

# config/routes.rb
devise_for :users, :controllers => { : omniauth_callbacks => "omniauth_callbacks" }
Step 7: Create omniauth_callbacks_controller.rb controller
# app/controllers/omniauth_callbacks_controller.rb

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def google_oauth2
    @user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
      if @user.persisted?
        flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
        sign_in_and_redirect @user, :event => :authentication
      else
        session["devise.google_data"] = request.env["omniauth.auth"]
        redirect_to new_user_registration_url
      end
  end
end
Step 8: Finally update user model and add the following block
# app/model/user.rb

def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
    data = access_token.info
    user = User.where(:omniauth => access_token.provider, :uid => access_token.uid ).first
    if user
      return user
    else
      registered_user = User.where(:email => access_token.info.email).first
      if registered_user
        return registered_user
      else
        user = User.create(name: data["name"],
          omniauth:access_token.provider,
          email: data["email"],
          uid: access_token.uid ,
          password: Devise.friendly_token[0,20],
        )
      end
   end
end