OAuth helps your app let users log in using other services safely. It avoids asking for passwords directly.
OAuth integration basics in Ruby on Rails
gem 'omniauth' gem 'omniauth-oauth2' # In config/initializers/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :provider_name, 'APP_ID', 'APP_SECRET' end
Replace provider_name with the service like google_oauth2 or facebook.
APP_ID and APP_SECRET come from the service's developer console.
provider :google_oauth2, 'GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET'
provider :facebook, 'FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET'
This example shows how to set up GitHub OAuth in Rails. When users log in via GitHub, the app gets their info and creates or finds a user. Then it saves the user ID in the session and redirects to the homepage with a welcome message.
# config/initializers/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :github, 'GITHUB_CLIENT_ID', 'GITHUB_CLIENT_SECRET' end # app/controllers/sessions_controller.rb class SessionsController < ApplicationController def create auth = request.env['omniauth.auth'] user = User.find_or_create_by(uid: auth['uid'], provider: auth['provider']) do |u| u.name = auth['info']['name'] u.email = auth['info']['email'] end session[:user_id] = user.id redirect_to root_path, notice: "Logged in as #{user.name}" end def failure redirect_to root_path, alert: 'Authentication failed.' end end # config/routes.rb Rails.application.routes.draw do get '/auth/:provider/callback', to: 'sessions#create' get '/auth/failure', to: 'sessions#failure' end
Always keep your APP_SECRET private and never share it.
Test OAuth flows in development using localhost URLs registered in the provider settings.
Handle authentication failures gracefully to improve user experience.
OAuth lets users log in using other services without sharing passwords.
Use OmniAuth middleware in Rails to connect with OAuth providers.
Handle callbacks to create or find users and manage sessions.
Practice
Solution
Step 1: Understand OAuth's role
OAuth allows users to authenticate using external services like Google or Facebook without sharing their passwords with your app.Step 2: Identify the correct purpose in Rails context
In Rails, OAuth integration is mainly for user login via third-party providers, not for password encryption or database tasks.Final Answer:
Allow users to log in using credentials from other services without sharing passwords -> Option BQuick Check:
OAuth = External login without password sharing [OK]
- Confusing OAuth with password encryption
- Thinking OAuth generates passwords
- Assuming OAuth manages database migrations
config/initializers/omniauth.rb file?Solution
Step 1: Recall OmniAuth middleware setup syntax
The standard way is to useRails.application.config.middleware.use OmniAuth::Builderwith a block specifying providers.Step 2: Match the correct syntax for GitHub provider
The block should callprovider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']inside the middleware use call.Final Answer:
Rails.application.config.middleware.use OmniAuth::Builder do provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'] end -> Option DQuick Check:
Middleware use with provider block = Rails.application.config.middleware.use OmniAuth::Builder do provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'] end [OK]
- Using incorrect middleware methods like add or insert
- Misplacing provider call outside the block
- Wrong OmniAuth configuration syntax
session[:user_id] be set to if the user is found?def github
auth = request.env['omniauth.auth']
user = User.find_by(uid: auth['uid'], provider: auth['provider'])
if user
session[:user_id] = user.id
redirect_to root_path
else
redirect_to login_path
end
endSolution
Step 1: Analyze user lookup and session assignment
The code finds a user by UID and provider from OAuth data. If found, it setssession[:user_id]touser.id.Step 2: Understand what
This is the user's unique database ID, used to track logged-in users in the session.user.idrepresentsFinal Answer:
The user's database ID -> Option AQuick Check:
session[:user_id] = user.id means database ID [OK]
- Confusing session user_id with provider or email
- Assuming session is not set
- Misreading user lookup logic
def google
auth = request.env['omniauth.auth']
user = User.find_or_create_by(uid: auth['uid']) do |u|
u.email = auth['info']['email']
u.provider = auth['provider']
end
session[:user_id] = user.id
redirect_to root_path
endSolution
Step 1: Check find_or_create_by conditions
The method only usesuid: auth['uid']to find or create a user, missingproviderin the lookup.Step 2: Understand impact of missing provider
Without provider, users with same UID from different providers may be treated as the same user, causing duplicates or wrong matches.Final Answer:
Missing provider in find_or_create_by conditions causes duplicate users -> Option AQuick Check:
Include provider in find_or_create_by to avoid duplicates [OK]
- Thinking block with find_or_create_by is invalid
- Misreading auth hash structure
- Assuming session order causes error
def oauth_callback
auth = request.env['omniauth.auth']
user = User.find_by(email: auth['info']['email'])
if user
# What should happen here?
else
user = User.create(
email: auth['info']['email'],
uid: auth['uid'],
provider: auth['provider']
)
end
session[:user_id] = user.id
redirect_to root_path
endSolution
Step 1: Understand the problem of duplicate accounts
Users may log in with different providers but same email. Creating new users each time causes duplicates.Step 2: Best practice is to link accounts
If a user with the email exists, update theiruidandproviderfields if missing to link OAuth data to one account.Final Answer:
Update user's uid and provider if missing, to link accounts -> Option CQuick Check:
Link accounts by updating uid/provider on existing email [OK]
- Creating new users for each provider causing duplicates
- Ignoring provider and uid fields
- Raising errors instead of linking accounts
Ready to prove it?
Pass the test and this pattern moves unknown
