You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails应用通过OmniAuth实现谷歌认证时出现nil:NilClass错误

问题排查与解决方案

核心问题定位

错误undefined method 'expired?' for nil:NilClass的直接原因是access_token变量为nil,根源是前端登录按钮直接指向回调URL,跳过了Google OAuth2的授权流程,导致OmniAuth无法获取有效授权响应,后续依赖access_token的逻辑自然出错。

分步修复

1. 修正前端登录按钮链接

当前按钮直接跳转到回调地址/auth/google_oauth2/callback是错误的。正确流程应先跳转到OmniAuth授权入口,由其引导用户完成Google授权后,再自动回调到指定地址。

修改按钮代码:

<%= link_to 'Sign in with Google', "/auth/google_oauth2" %>

2. 验证OmniAuth响应完整性

在SessionsController#create中保留日志输出,确认request.env['omniauth.auth']包含uid、provider、info等关键字段:

logger.info("OmniAuth完整响应: #{request.env['omniauth.auth'].inspect}")

3. 补充模型OAuth相关字段(可选)

若后续需要存储token用于刷新操作,给buyer表添加对应字段:

rails generate migration AddOauthFieldsToBuyer access_token:string refresh_token:string expires_at:datetime
rails db:migrate

并在from_omniauth方法中补充赋值:

def self.from_omniauth(response)
  Buyer.find_or_create_by(uid: response[:uid], provider: response[:provider]) do |u|
    u.fname = response[:info][:name]
    u.email = response[:info][:email]
    u.password = SecureRandom.hex(15)
    # 新增token存储逻辑
    u.access_token = response[:credentials][:token]
    u.refresh_token = response[:credentials][:refresh_token]
    u.expires_at = Time.at(response[:credentials][:expires_at])
  end
end

4. 优化OmniAuth配置

确保配置中明确请求必要权限,且环境变量加载正常:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
    provider_ignores_state: true,
    scope: 'email profile'
end

验证修复

启动Rails服务器后,点击登录按钮会跳转至Google授权页面,完成授权后自动回调到/auth/google_oauth2/callback,即可正常创建/查找用户并完成登录。

内容的提问来源于stack exchange,提问作者Sreyash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:10:02