Google Login in Rails 7 with devise
Tags: ruby, rails, webdev, beginners
Published: 2023-06-20 06:06:37

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](https://dev.to/ahmadraza/authentication-using-devise-in-rails-7-3dn0)._

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"
```

Then, run the following command to install the gems:

```
bundle install
```

---

## 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]
```

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
```

Add the below code in your migration:

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

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
```

---

## 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
```

---

## Step 4: Add Routes

Open `config/routes.rb` and the routes:

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

---

## Step 5: Set Up a Google API Console Project

Visit the [Google API Console](https://console.developers.google.com/) and create a new project as below:

![Google API Console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yntoygi2z9zfm0rl9e4.png)

![How to create a new project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vf8w6971a5spszryvraq.png)

---

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4t1a6q6g2lguipkb8tr.png)

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'
```

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'

```

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"} %>
```

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

You can check the gem's repo [here](https://github.com/zquestz/omniauth-google-oauth2).

Thanks for reading! 🙂