尝试连接到 Google Oauth for google API 时 JWT 无效

Posted

技术标签:

【中文标题】尝试连接到 Google Oauth for google API 时 JWT 无效【英文标题】:Invalid JWT when trying to connect to Google Oauth for google API 【发布时间】:2016-08-22 21:22:05 【问题描述】:

我试图通过 JWT 通过 OAuth 连接到 Google API,但我不断收到此错误:

"error": "invalid_grant", "error_description": "Invalid JWT: Token 必须是短命的 token 并且在合理的时间范围内"

在我的 JWT calim 中,我将 iat 设置为当前时间减去 1970-01-01 以秒为单位,并将 exp 设置为 iat + 3600,所以我不知道为什么我仍然会收到此错误。如果有人知道答案,请告诉 meeeeee!

【问题讨论】:

您是否在提出自己的 JWT 声明? time 需要是当前时间 NTP en.wikipedia.org/wiki/Network_Time_Protocol 感谢您的回复,我将时间设置为 UTC,现在我收到无效签名错误,您知道我做错了什么吗? $sig = hash_hmac('sha256', utf8_encode($base64encodedHeaderAndPayload), "-----BEGIN PRIVATE KEY-----\n privatekey \n-----END PRIVATE KEY -----\n"); $signature = base64url_encode($sig); 请注意一个线索,我也曾尝试创建自己的 JWT 令牌以使其正常工作***.com/questions/33438494/… 我使用的一直是使用 Google 的客户端库。您使用的是什么语言,也许您可​​以将客户端库代码分开。 【参考方案1】:

不确定你是否曾经让它工作,但使用 php 函数 openssl_sign(),以下简单步骤对我有用:

//helper function
function base64url_encode($data)  
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 


//Google's Documentation of Creating a JWT: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests

//Base64url encoded JSON header
$jwtHeader = base64url_encode(json_encode(array(
    "alg" => "RS256",
    "typ" => "JWT"
)));
//Base64url encoded JSON claim set
$now = time();
$jwtClaim = base64url_encode(json_encode(array(
    "iss" => "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
    "scope" => "https://www.googleapis.com/auth/prediction",
    "aud" => "https://www.googleapis.com/oauth2/v4/token",
    "exp" => $now + 3600,
    "iat" => $now
)));
//The base string for the signature: Base64url encoded JSON header.Base64url encoded JSON claim set
openssl_sign(
    $jwtHeader.".".$jwtClaim,
    $jwtSig,
    $your_private_key_from_google_api_console,
    "sha256WithRSAEncryption"
);
$jwtSign = base64url_encode($jwtSig);

//Base64url encoded JSON header.Base64url encoded JSON claim set.Base64url encoded signature
$jwtAssertion = $jwtHeader.".".$jwtClaim.".".$jwtSig;

【讨论】:

对不起,我一直忘记更新这个。这确实是正确的答案!虽然我不再需要使用它,因为 App Engine 现在允许我直接访问 Cloud Storage。但仍然感谢您的正确答案! :) 嘿@Joseph Shih 我有类似的问题,我的错误是Invalid JWT Signature.。你能分享你的 POST 请求吗?我想我在请求正文中遇到了grant_type 的问题。 @Michel,无效的 JWT 签名错误意味着您的签名无法验证您的 $jwtHeader 和 $jwtClaim。您是否使用了正确的 ISS(服务帐户的电子邮件地址)以及您是否使用 API 控制台中的私钥。另外,请记住,您需要对签名进行 base-64 编码(如上面的示例)。 没关系@JosephShih 我能够修复它。我在这里发布了答案:***.com/questions/48106432/… 仍然感谢您的回复:)【参考方案2】:

我遇到了同样的问题,我通过将我的虚拟机时间与公共 ntpserver 同步来解决它:

ntpdate ntp.ubuntu.com

【讨论】:

【参考方案3】:

如果您看到此错误,您必须为令牌设置正确的过期时间。示例:

var currentTime = new Date().getTime() / 1000; //must be in seconds
var exp = currentTime + 60;

var auth_claimset = 
      iss       :   "...",
      scope     :   "...",
      aud       :   "...",
      exp       :   exp,
      iat       :   currentTime 
;

【讨论】:

【参考方案4】:

如果您在此处执行 HTTP/Rest 下的步骤: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#formingheader,您会看到您的服务帐户支持 RSA SHA-256,而且您似乎使用 HMAC。

【讨论】:

所以我修改了下面的代码:' $sig = hash('SHA256', $headerAndPayload, $secret); $signature = base64url_encode($sig); $jwt = $headerAndPayload 。 “。” . $签名; ' 由于某种原因,我不断收到无效的签名。 $secret 是我从服务帐户密钥 json 文件中获得的私钥。你知道怎么回事吗? 我刚刚发现在 PHP 中使用 hash 不使用密钥,所以我应该仍然使用 hash_hmac,但我没有得到结果:/ 似乎有创建符合规范的 JWT 的签名库。例如:github.com/namshi/jose【参考方案5】:

如果您在本地开发机器上使用 WSL2 后端在 Windows 中的 Docker 上进行测试,WSL 也会发生这种情况。

你需要安装ntpdate

sudo apt install ntpdate

那么你需要设置时间。

sudo ntpdate time.windows.com

关于它的好文章在这里 - https://tomssl.com/fixing-clock-drift-in-wsl2-using-windows-terminal/

【讨论】:

以上是关于尝试连接到 Google Oauth for google API 时 JWT 无效的主要内容,如果未能解决你的问题,请参考以下文章

无需 oAuth 即可连接到非 Google 服务的 Gmail 插件

将 ColdFusion 连接到 Google Bigquery

如何在没有 oAuth 身份验证的情况下连接到 Google Calendar API?

Gmail插件可在没有oAuth的情况下连接到非Google服务

如何将 Google App Engine (Flex) Go 应用程序连接到 Google Cloud Postgres 实例

如何使用 OAuth2 授权 Google 分析数据 API