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

使用Doorkeeper实现Google登录时遇JWT解码错误求助

问题分析与解决方案

首先,JWT::DecodeError - Invalid segment encoding 错误几乎都是传递的断言格式不正确或验证逻辑配置错误导致的,大概率不是依赖库的bug,以下是具体分析和修复步骤:

核心问题定位

你提到在resource_owner_from_assertion块中调用auth0.auth_hash时出错,这里有两个关键问题:

  1. 混淆了断言类型:Doorkeeper的assertion授权模式期望传入的是标准JWT格式的身份断言,而Google OAuth2返回的access_token并非JWT(仅id_token是符合标准的JWT)。如果你的请求中把Google的access_token当成assertion参数传递,必然会触发JWT解码失败。
  2. 错误调用了Auth0的方法:auth0.auth_hash是Auth0 Omniauth策略的专属方法,和Google OAuth2的流程不兼容,在Doorkeeper的断言授权逻辑里不应该使用它。

修复步骤

1. 确保传递的是Google ID Token而非Access Token

在前端或测试页面完成Google授权后,要从返回的参数中提取id_token,作为assertion参数传递给Doorkeeper的token接口(/oauth/token),请求参数示例:

POST /oauth/token
Content-Type: application/json

{
  "grant_type": "assertion",
  "assertion": "GOOGLE_ID_TOKEN_HERE",
  "client_id": "YOUR_DOORKEEPER_CLIENT_ID",
  "client_secret": "YOUR_DOORKEEPER_CLIENT_SECRET"
}

2. 修正Doorkeeper的断言授权配置

在config/initializers/doorkeeper.rb中,替换原有的resource_owner_from_assertion逻辑,直接处理Google的ID Token:

resource_owner_from_assertion do
  begin
    # 获取Google的公钥用于验证JWT签名
    jwks_raw = Net::HTTP.get(URI("https://www.googleapis.com/oauth2/v3/certs"))
    jwks_keys = Array(JSON.parse(jwks_raw)["keys"])

    # 解码并验证Google ID Token
    decoded_token = JWT.decode(
      assertion,
      nil,
      true, # 开启签名验证
      algorithm: "RS256",
      iss: "https://accounts.google.com",
      verify_iss: true,
      audience: ENV["GOOGLE_CLIENT_ID"], # 替换为你的Google客户端ID
      verify_aud: true
    ) do |header|
      # 根据JWT头部的kid匹配对应的公钥
      jwks_keys.find { |k| k["kid"] == header["kid"] }
    end

    user_info = decoded_token.first
    # 查找或创建系统用户(根据你的业务逻辑调整)
    User.find_or_create_by(email: user_info["email"]) do |user|
      user.name = user_info["name"]
      user.avatar_url = user_info["picture"]
      # 其他必要字段赋值
    end
  rescue JWT::DecodeError => e
    Rails.logger.error("Google ID Token解码失败: #{e.message}")
    nil # 返回nil会导致Doorkeeper拒绝授权
  end
end

3. 验证配置细节

  • 确认config/initializers/doorkeeper.rb中已正确开启断言授权:
    grant_flows %w[password assertion]
    
  • 检查Google Cloud Console中的客户端ID是否和代码中的ENV["GOOGLE_CLIENT_ID"]一致,且授权回调地址配置正确。

版本兼容性检查

目前你使用的版本组合(Rails 7.0.8.4、Ruby 3.1.4、doorkeeper 5.6.6、doorkeeper-grants_assertion 0.3.1)不存在已知的兼容性bug,无需调整版本,重点放在上述配置修正上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 21:03:27