在本文中,我们将探讨如何在 Rails 8 中,基于 Rails 内置的认证系统,使用 OmniAuth 实现 Google 登录,而无需 Devise。
创建基本认证
生成认证
在 Rails 8 中,自带一个认证生成器,我们可以直接使用。它会创建 User 和 Session 模型,以及登录应用所需的控制器和视图。更多信息请参阅 官方指南
bin/rails generate authentication移除密码
因为我只想启用 Google 登录,并移除其他登录方式。所以,数据库中的 users.password_digest 列就没有必要保留了,同时删除相关文件。
让我们从 [timestamp]_create_users.rb 中移除 t.string :password_digest, null: false,并更新 User 模型,删除 hassecurepassword 这一行,因为它不再需要了。
运行迁移
然后迁移数据库,以添加 User 和 Session 表。
bin/rails db:migrate实现 Google 登录
添加 OmniAuth Gem
将所需的 gem 添加到你的 Gemfile 中,然后运行 bundle install 来安装这些 gem。
# OmniAuth and Google OAuth
gem "omniauth", "~> 2.1"
gem "omniauth-google-oauth2", "~> 1.2"
gem "omniauth-rails_csrf_protection", "~> 1.0"配置 OmniAuth
为 OmniAuth 创建一个初始化器:
touch config/initializers/omniauth.rb然后添加以下配置。
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"]
end确保在部署配置中设置了 GOOGLECLIENTID 和 GOOGLECLIENTSECRET 环境变量。请阅读 Google OAuth 官方文档,了解如何获取 GOOGLE_CLIENT_ID 和 GOOGLE_CLIENT_SECRET 的值。
创建 SocialAccount 模型
虽然本文只需要实现 Google 登录,但以后我们可能还需要添加其他登录方式,比如 GitHub 登录,所以最好将社交账户信息保存到另一个模型中。这里我们称之为 SocialAccount。
rails generate model SocialAccount user:references provider:string uid:string auth_data:json接下来,我们按如下方式更新生成的模型:
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我们添加了函数 self.from_omniauth,用于通过电子邮件创建或查找 User。
更新路由和 SessionsController
接下来,我们需要在 config/routes.rb 文件中添加 oauth 路由。
get "/auth/:provider/callback", to: "sessions#create"
get "/auth/failure", to: "sessions#failure"然后,更新 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添加 Google 登录按钮
在 sessions/new.html.erb 中添加一个 Google 登录按钮:
<%= button_to "Sign in with Google",
"/auth/google_oauth2",
method: :post,
class: "btn btn--primary btn--block",
data: { turbo: false } %>现在,我们已经成功地为 Rails 应用添加了 Google 登录功能。
结论
通过这种设置,你可以在 Rails 应用中实现 Google 登录,而无需使用 Devise。借助 OmniAuth,你还可以扩展应用以支持其他提供商,如 Facebook 或 GitHub。

正在加载评论…