尝试连接到 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 实例