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

如何通过Ruby的Signet获取带Refresh Token的Gmail API OAuth2令牌?

解决Signet::OAuth2获取Refresh Token的问题

核心问题分析

你当前的代码存在两个关键错误:

  1. 在调用fetch_access_token!之前尝试访问client.refresh_token——此时Signet还未完成token获取流程,该属性尚未赋值,因此会提示未定义。
  2. access_type: 'offline'参数位置错误:这个参数需要在引导用户授权的请求阶段添加,而非回调阶段的Client初始化中。

正确实现步骤

1. 生成授权跳转URL(用户点击授权按钮的前置逻辑)

必须在生成授权URL时指定access_type: 'offline',告知Google你需要离线访问权限(即返回refresh token):

# 生成授权URL的代码
client = Signet::OAuth2::Client.new({
  client_id: ENV.fetch('GOOGLE_API_CLIENT_ID'),
  client_secret: ENV.fetch('GOOGLE_API_CLIENT_SECRET'),
  token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
  redirect_uri: url_for(:action => :callback),
  scope: 'https://www.googleapis.com/auth/gmail.modify', # 替换为你实际需要的Gmail权限
  access_type: 'offline', # 关键:开启离线访问,才会返回refresh token
  include_granted_scopes: 'true'
})

# 引导用户跳转到Google授权页面
redirect_to client.authorization_uri.to_s

2. 回调处理(获取Token)

在回调接口中,必须先调用fetch_access_token!完成token获取,之后才能读取refresh_token:

# 回调Action的代码
client = Signet::OAuth2::Client.new({
  client_id: ENV.fetch('GOOGLE_API_CLIENT_ID'),
  client_secret: ENV.fetch('GOOGLE_API_CLIENT_SECRET'),
  token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
  redirect_uri: url_for(:action => :callback),
  code: params[:code]
})

# 先执行token获取请求
response = client.fetch_access_token!

# 此时才能正确获取refresh_token和access_token
refresh_token = client.refresh_token
access_token = response['access_token']

额外注意事项

  • 重复授权不返回Refresh Token:如果用户之前已经授权过相同权限范围且包含离线访问,Google默认不会再次返回refresh token。若需要强制获取,在生成授权URL时添加prompt: 'consent'参数,强制用户重新确认授权:
    client = Signet::OAuth2::Client.new({
      # 其他参数不变
      access_type: 'offline',
      prompt: 'consent' # 强制重新授权,确保返回refresh token
    })
    
  • 保存Refresh Token:获取到refresh token后,务必持久化存储(比如数据库),后续可以用它刷新access token,无需用户再次授权。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:25:17