Rails 6中使用Devise的GoogleOauth2进行身份验证失败问题咨询
Rails 6 Devise 接入Google OAuth2 提示邮箱未授权的解决方案
认证流程最终阶段收到flash提示:Could not authenticate you from Google because user@gmail.com is not authorized,无法完成登录,运行日志如下:
DEBUG -- omniauth: (google_oauth2) Request phase initiated. Started GET "/users/auth/google_oauth2/callback?state=bfcb81a9dc331af478dcd5ccb3dda620894b0e577d1fabe8&code=4%2F0AX4XfWifE4F2PzgdO28g5GSMPg28WltztgoSpJHfM-CsQl8oplhFAKix-WJZAf9LRREIHw&scope=email+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcontacts.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&prompt=none" for ::1 at 2021-07-23 11:59:55 +0300 D, [2021-07-23T11:59:55.042930 #13482] DEBUG -- omniauth: (google_oauth2) Callback phase initiated. Processing by Users::OmniauthCallbacksController#google_oauth2 as HTML Parameters: {"state"=>"bfcb81a9dc331af478dcd5ccb3dda620894b0e577d1fabe8", "code"=>"4/0AX4XfWifE4F2PzgdO28g5GSMPg28WltztgoSpJHfM-CsQl8oplhFAKix-WJZAf9LRREIHw", "scope"=>"email openid https://www.googleapis.com/auth/contacts.readonly https://www.googleapis.com/auth/userinfo.email", "authuser"=>"0", "prompt"=>"none"} Redirected to http://localhost:3000/users/sign_in
排查与解决步骤
- 检查Google Cloud后台测试用户配置
开发阶段的OAuth应用默认处于「测试」状态,仅允许在「OAuth同意屏幕」页面中添加的测试用户登录。请将user@gmail.com添加到测试用户列表,或将应用发布为正式状态即可解除限制。 - 检查Omniauth配置的域名限制
查看config/initializers/devise.rb中Google OAuth2的配置,如果添加了hd(hosted domain)参数限制登录邮箱域名,个人Gmail邮箱会被拦截:
去掉# 错误示例:限制仅公司域名可登录 config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], hd: 'yourcompany.com'hd参数,或修改为允许的域名即可。 - 检查回调控制器的自定义白名单逻辑
查看app/controllers/users/omniauth_callbacks_controller.rb中的回调处理代码,确认是否存在自定义的邮箱白名单校验逻辑,若存在请将测试邮箱加入白名单,或调整校验规则:def google_oauth2 auth = request.env["omniauth.auth"] # 错误示例:硬编码限制仅指定邮箱可登录 unless auth.info.email == 'admin@yourcompany.com' flash[:alert] = "邮箱未授权" redirect_to new_user_session_path and return end # 后续登录逻辑 end - 检查User模型的保存校验
查看app/models/user.rb中的from_omniauth方法,确认OAuth返回的字段是否满足模型的必填项校验,若存在必填字段未赋值会导致用户保存失败,跳转回登录页:def self.from_omniauth(auth) where(provider: auth.provider, uid: auth.uid).first_or_create do |user| user.email = auth.info.email user.password = Devise.friendly_token[0, 20] user.name = auth.info.name # 若模型有name必填字段,必须赋值,否则会保存失败 end end
内容的提问来源于stack exchange,提问作者Anton Lukashevich
相关产品推荐
相关产品推荐

