使用Doorkeeper实现Google登录时遇JWT解码错误求助
问题分析与解决方案
首先,JWT::DecodeError - Invalid segment encoding 错误几乎都是传递的断言格式不正确或验证逻辑配置错误导致的,大概率不是依赖库的bug,以下是具体分析和修复步骤:
核心问题定位
你提到在resource_owner_from_assertion块中调用auth0.auth_hash时出错,这里有两个关键问题:
- 混淆了断言类型:Doorkeeper的
assertion授权模式期望传入的是标准JWT格式的身份断言,而Google OAuth2返回的access_token并非JWT(仅id_token是符合标准的JWT)。如果你的请求中把Google的access_token当成assertion参数传递,必然会触发JWT解码失败。 - 错误调用了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
相关产品推荐
相关产品推荐

