返回

Google 日历 OAuth 授权的“invalid_grant / Invalid JWT Signature”错误:故障排除指南

php

Google 日历 OAuth 授权中的“invalid_grant / Invalid JWT Signature”错误:故障排除指南

简介

在使用 Google 服务帐号为 Google 日历应用程序生成访问令牌时,开发者可能会遇到“invalid_grant / Invalid JWT Signature”错误。本文旨在提供一个循序渐进的指南,帮助你解决此问题,确保成功获取访问令牌。

验证服务帐号凭据

确保服务帐号凭据有效

  • 检查你的服务帐号凭据是否有效。
  • 确保私钥文件正确无损。
  • 验证私钥文件具有适当的权限。

构建有效的 JWT

使用正确的声明

  • 构建 JWT 时,包括以下声明:
    • “iss”(发行者)
    • “aud”(受众)
    • “iat”(签发时间)
    • “exp”(到期时间)

使用服务帐号私钥签名

  • 确保使用服务帐号的私钥对 JWT 进行签名。
  • 利用 JWT 编码器将声明编码为 JWT。

发送授权请求

向 Google 令牌端点发送请求

  • 向 Google 的令牌端点(https://www.googleapis.com/oauth2/v3/token)发送授权请求。
  • 在请求中包含参数:“grant_type”(urn:ietf:params:oauth:grant-type:jwt-bearer)和“assertion”(编码后的 JWT)。
  • 使用适当的请求头,例如“Content-Type: application/x-www-form-urlencoded”。

响应解析和故障排除

解析 Google 响应

  • 解析 Google 的响应,检查是否存在“invalid_grant”或“Invalid JWT Signature”错误。

仔细检查错误原因

  • 如果出现错误,请仔细检查:
    • JWT 签名是否正确。
    • JWT 是否已过期。
    • 服务帐号是否有权访问 Google 日历 API。
    • 请求 URL 和参数是否正确。

代码示例

以下代码示例演示如何构建 JWT 并向 Google 令牌端点发送授权请求:

// 获取服务帐号凭据
$key = file_get_contents("./certs/certificado.pem");

// 构建 JWT 声明
$token = array(
    "iss" => "**** *@**** ***.iam.gserviceaccount.com",
    "aud" => "https://www.googleapis.com/oauth2/v3/token",
    "iat" => time(),
    "exp" => time() + 60,
    "scope" => "https://www.googleapis.com/auth/calendar.readonly"
);

// 使用 JWT 编码器生成 JWT
$jwt = JWT::encode($token, $key, 'RS256');

// 发送授权请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.googleapis.com/oauth2/v3/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=" . urlencode($jwt));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);

// 解析响应
$response = json_decode($result, true);

// 检查是否有错误
if (isset($response['error'])) {
    if ($response['error'] === 'invalid_grant') {
        echo "无效的 JWT 签名。";
    } else {
        echo $response['error_description'];
    }
} else {
    // 获取访问令牌
    $access_token = $response['access_token'];
}

其他提示

  • 确保你的请求是安全的。
  • 使用 Google API 客户端库来简化授权过程。
  • 遵循 Google 的文档和最佳实践。

结论

解决“invalid_grant / Invalid JWT Signature”错误需要彻底的故障排除过程。通过验证凭据、构建有效的 JWT、发送正确的授权请求并解析响应,开发者可以成功获取 Google 日历的访问令牌。

常见问题解答

  1. 为什么会出现“invalid_grant”错误?

    • 可能是 JWT 签名不正确,JWT 已过期,服务帐号无权访问 API,或请求 URL/参数错误。
  2. 如何防止“Invalid JWT Signature”错误?

    • 确保使用服务帐号私钥对 JWT 进行签名,并检查签名是否正确。
  3. 什么是有效 JWT 的必需声明?

    • 发行人(“iss”)、受众(“aud”)、签发时间(“iat”)和到期时间(“exp”)。
  4. 应该使用什么请求头来发送授权请求?

    • 使用“Content-Type: application/x-www-form-urlencoded”请求头。
  5. 可以使用哪些库来简化授权过程?

    • Google API 客户端库是一个不错的选择。