DEV Community

Cover image for Google Login in Rails 7 with devise
Ahmad Raza
Ahmad Raza

Posted on

Google Login in Rails 7 with devise

Google login can provide a convenient and seamless authentication option for your users. In this comprehensive guide, we'll walk you through the steps to integrate Google login into your Rails 7 app, allowing users to authenticate using their Google accounts.

I'm assuming that you already have installed and implemented devise gem in your rails app. If not check this article.

Let's get started!


Step 1: Add Required Gems

In your Rails app's Gemfile, make sure you have the following gems:



gem 'omniauth-google-oauth2'
gem "omniauth-rails_csrf_protection"


Enter fullscreen mode Exit fullscreen mode

Then, run the following command to install the gems:



bundle install


Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Devise Model

Add the following code in your devise model (i'll be using User):



# models/user.rb
:omniauthable, omniauth_providers: [:google_oauth2]


Enter fullscreen mode Exit fullscreen mode

Now we need to add two fields uid and provider in our devise model (in my case User).

  1. uid (User ID): It stores a unique identifier associated with the user's account from the OAuth provider (in this case, Google). Each user has a distinct uid assigned by the provider, which allows your application to uniquely identify them.

  2. provider: It indicates the name of the OAuth provider being used for authentication (e.g., "google_oauth2"). This field helps differentiate between different authentication methods and allows your application to handle multiple authentication providers if needed.

Generate the migration:



rails g migration AddFieldsToUser


Enter fullscreen mode Exit fullscreen mode

Add the below code in your migration:



def change
  change_table :users, bulk: true do |t|
    t.string :provider
    t.string :uid
  end
end


Enter fullscreen mode Exit fullscreen mode

Run rails db:migrate to add these fields to your table.

Now, add the below code in your devise model. Mine in user.rb:



def self.from_google(u)
    create_with(uid: u[:uid], provider: 'google',
                password: Devise.friendly_token[0, 20]).find_or_create_by!(email: u[:email])
end


Enter fullscreen mode Exit fullscreen mode

Step 3: Configure Controller

Create a users/omniauth_callbacks_controller.rb file inside the controllers directory and paste the below code:



# app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   def google_oauth2
     user = User.from_google(from_google_params)

     if user.present?
       sign_out_all_scopes
       flash[:notice] = t 'devise.omniauth_callbacks.success', kind: 'Google'
       sign_in_and_redirect user, event: :authentication
     else
       flash[:alert] = t 'devise.omniauth_callbacks.failure', kind: 'Google', reason: "#{auth.info.email} is not authorized."
       redirect_to new_user_session_path
     end
    end

    def from_google_params
      @from_google_params ||= {
        uid: auth.uid,
        email: auth.info.email
      }
    end

    def auth
      @auth ||= request.env['omniauth.auth']
    end
end


Enter fullscreen mode Exit fullscreen mode

Step 4: Add Routes

Open config/routes.rb and the routes:



# config/routes.rb
devise_for :user,
      controllers: {
         omniauth_callbacks: 'users/omniauth_callbacks'
      }


Enter fullscreen mode Exit fullscreen mode

Step 5: Set Up a Google API Console Project

Visit the Google API Console and create a new project as below:

Google API Console

How to create a new project


You can give any name to your project. I named it Google Login.

After entering the name click Create.

And then go into your google login project. There will be a dropdown in the navbar (i've showed it in the first picture), you can use it to change your project.

  1. Go to OAuth consent screen
  2. Choose user type External
  3. Click Create
  4. Fill all the fields
  5. Scroll down and click Save and continue.

Next follow the below steps:

Create Credentials

  1. Select Application Type Web application
  2. Enter any name
  3. Go to your console/terminal and type the command rails routes | grep /callback. Copy the URL...
  4. Go to your browser and click on Add URI button
  5. Paste the copied url in URL field such as http://localhost:3000/user/auth/google_oauth2/callback
  6. Click Create

Once you have created the project, a popup will display your client ID and client secret. Make sure to save this information for future use.

Now that you have obtained your client ID and client secret, let's proceed with the configuration of Google login in your Rails app.

Step 6: Implement Google Login

Open up config/initializers/devise.rb file and paste the below code:



# config/initializers/devise.rb

config.omniauth :google_oauth2, 'GOOGLE_OAUTH_CLIENT_ID', 'GOOGLE_OAUTH_CLIENT_SECRET'


Enter fullscreen mode Exit fullscreen mode

My file looks like this:



# config/initializers/devise.rb

# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
config.omniauth :google_oauth2, 'GOOGLE_OAUTH_CLIENT_ID', 'GOOGLE_OAUTH_CLIENT_SECRET'



Enter fullscreen mode Exit fullscreen mode

Now just add the login button in any of your views.



<%= button_to 'Login with Google', user_google_oauth2_omniauth_authorize_path, method: :post, :data => {turbo: "false"} %>


Enter fullscreen mode Exit fullscreen mode

Congratulations! 🎉 You have successfully added Google login to your Rails 7 app.

You can check the gem's repo here.

Thanks for reading! 🙂

Top comments (8)

Collapse
 
rafaeldev profile image
Rafael Gomes

Thank you for your post!

I had a problem with the CSRF token, it's because I'm putting Google login button inside the old sign-in form.

omniauth: (google_oauth2) Authentication failure! ActionController::InvalidAuthenticityToken

I'm posting this to other guys 🫡

Collapse
 
kumarkalyan profile image
Kumar Kalyan

Nice article! easy to understand

Collapse
 
ahmadraza profile image
Ahmad Raza

Btw, I loved your weather app article. It was awesome!

Collapse
 
ahmadraza profile image
Ahmad Raza • Edited

Thanks for your kind words @kumarkalyan! 🚀

I'm really glad that you found this article helpful 🙂

Collapse
 
ahmadraza profile image
Ahmad Raza

Feel free to ask any doubt!

Collapse
 
gmcamposano profile image
gmcamposano

Hello! Is there a reason why you configured differently from the proposed controller methods and model method from the docs? Ex. users/omniauth_callbacks_controller.rb is different from the docs and also the from_google method which uses the "unless user ..."

Collapse
 
noctivityinc profile image
noctivityinc

This is amazing. How would you customize the sign up and sign in buttons for google?

Collapse
 
nick_mealey_e809e2ab09fef profile image
Nick Mealey

In routes.rb shouldn't it be devise_for :users?