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"
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
).
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.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 and create a new project as below:
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.
- Go to
OAuth consent screen
- Choose user type
External
- Click Create
- Fill all the fields
- Scroll down and click
Save and continue
.
Next follow the below steps:
- Select Application Type
Web application
- Enter any name
- Go to your console/terminal and type the command
rails routes | grep /callback
. Copy the URL... - Go to your browser and click on
Add URI
button - Paste the copied url in
URL
field such ashttp://localhost:3000/user/auth/google_oauth2/callback
- 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.
Thanks for reading! 🙂
Top comments (8)
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 🫡
Nice article! easy to understand
Btw, I loved your weather app article. It was awesome!
Thanks for your kind words @kumarkalyan! 🚀
I'm really glad that you found this article helpful 🙂
Feel free to ask any doubt!
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 ..."
This is amazing. How would you customize the sign up and sign in buttons for google?
In routes.rb shouldn't it be devise_for :users?