This guide demonstrates how to implement Google Login in a Rails application using OmniAuth, without relying on the Devise gem. We’ll utilize OmniAuth for authentication and connect it to a basic Rails authentication system.
Create Basic Authentication
Generate Authentication
in Rails 8, it comes with an authentication generator that we can use. It creates User and Session models and the controllers and views necessary to login to our application. you can find more in the Official Guides
bin/rails generate authentication
Remove Password
because I only want to enable Google Login and remove other login method. so, there is no need to keep the users.password_digest
column in database, and delete related file.
let’s remove t.string :password_digest, null: false
from [timestamp]_create_users.rb
and update the User model to remove the has_secure_password line, as it’s no longer needed.
Run migration
Then migrate the database to add the User and Session tables.
bin/rails db:migrate
Implement Google Login
Add OmniAuth Gems
Add the required gems to your Gemfile, then run bundle install
to install the gems.
# OmniAuth and Google OAuth
gem "omniauth", "~> 2.1"
gem "omniauth-google-oauth2", "~> 1.2"
gem "omniauth-rails_csrf_protection", "~> 1.0"
Configure OmniAuth
Create an initializer for OmniAuth:
touch config/initializers/omniauth.rb
then add the following configuration.
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"]
end
Ensure that you have the GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables set in your deployment configuration. read the Official Google Oauth Document to learn how to get GOOGLE_CLIENT_ID
and GOOGLE_CLIENT_SECRET
value.
Create SocialAccount Model
although in this post, we only need to implement Google Login, but maybe later we may need to add other login method, such as Github Login, so it’s better to save social account info into other model. in this case, it’s called SocialAccount
.
rails generate model SocialAccount user:references provider:string uid:string auth_data:json
next, we update generated model as follows:
class SocialAccount < ApplicationRecord
belongs_to :user
validates :provider, presence: true
validates :uid, presence: true, uniqueness: { scope: :provider }
def self.from_omniauth(auth)
social_account = find_or_initialize_by(provider: auth.provider, uid: auth.uid)
unless social_account.persisted?
user = User.find_or_create_by!(email_address: auth.info.email) do |u|
u.name = auth.info.name
u.avatar_url = auth.info.image
end
social_account.user = user
social_account.save!
end
social_account
end
end
we add function self.from_omniauth
to create or find User
by email.
Update routes and SessionsController
next we need to add oauth routes to config/routes.rb
file.
get "/auth/:provider/callback", to: "sessions#create"
get "/auth/failure", to: "sessions#failure"
then, upate SessionsController
class SessionsController < ApplicationController
def create
auth = request.env["omniauth.auth"]
social_account = SocialAccount.from_omniauth(auth)
start_new_session_for social_account.user
redirect_to after_authentication_url
end
def failure
redirect_to root_path, alert: "Authentication failed, please try again."
end
end
Add Google Login button
Add a button for Google Login in your sessions/new.html.erb:
<%= button_to "Sign in with Google",
"/auth/google_oauth2",
method: :post,
class: "btn btn--primary btn--block",
data: { turbo: false } %>
now we successfully add Google Login to our Rails application.
Conclusion
This setup allows you to implement Google Login in your Rails application without using Devise. With OmniAuth, you can extend the application to support other providers like Facebook or GitHub.