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

PHP服务器通过REST调用Google API:服务账号是否需刷新令牌及获取方法

服务账号访问Google API的REST方式说明

嘿,刚好对这块熟,给你掰扯清楚:

首先明确一点:服务账号模式下完全不需要刷新令牌!

和咱们平时用的普通OAuth2授权码流程不一样,服务账号是通过生成**JWT(JSON Web Token)**来换取访问令牌的,访问令牌过期后直接重新生成新的就行,根本不需要刷新令牌这个环节——这是服务账号的核心特性之一,比普通流程少了一步维护刷新令牌的麻烦。

那具体怎么通过REST获取可用的访问令牌呢?给你一步步拆解:

1. 准备好服务账号密钥

先从Google Cloud控制台下载服务账号的JSON密钥文件,里面会包含client_email、private_key这两个关键字段,后面要用到。

2. 构造JWT内容

JWT分为Header、Payload、Signature三部分:

  • Header:固定格式,指定签名算法为RS256:
    {
      "alg": "RS256",
      "typ": "JWT"
    }
    
  • Payload:需要包含这些必填字段:
    • iss:就是密钥里的client_email
    • scope:你要访问的API权限范围,比如访问Drive只读就填https://www.googleapis.com/auth/drive.readonly,多个scope用空格分隔
    • aud:固定为https://oauth2.googleapis.com/token
    • exp:令牌过期时间戳,建议设为当前时间+3600秒(1小时,Google允许的最长有效期)
    • iat:当前时间戳(令牌生成时间)

3. 签名生成完整JWT

用密钥里的private_key对Header和Payload的Base64URL编码拼接后的字符串进行RS256签名,得到完整的JWT字符串。PHP里可以用openssl_sign函数来实现。

4. 发送请求换取访问令牌

向https://oauth2.googleapis.com/token发送POST请求,参数如下:

  • grant_type:固定值urn:ietf:params:oauth:grant-type:jwt-bearer
  • assertion:刚才生成的完整JWT字符串

请求成功后,响应里会返回access_token,用这个令牌就可以调用对应的Google API了。

给你个PHP原生实现的示例片段

<?php
// 加载服务账号密钥
$serviceAccountKey = json_decode(file_get_contents('path/to/your/service-account-key.json'), true);

// 构造JWT Header
$header = json_encode([
    'alg' => 'RS256',
    'typ' => 'JWT'
]);

// 构造JWT Payload
$now = time();
$payload = json_encode([
    'iss' => $serviceAccountKey['client_email'],
    'scope' => 'https://www.googleapis.com/auth/drive.readonly',
    'aud' => 'https://oauth2.googleapis.com/token',
    'exp' => $now + 3600,
    'iat' => $now
]);

// Base64URL编码工具函数
function base64UrlEncode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

$encodedHeader = base64UrlEncode($header);
$encodedPayload = base64UrlEncode($payload);

// 拼接待签名的字符串
$signatureInput = $encodedHeader . '.' . $encodedPayload;

// 生成签名
openssl_sign($signatureInput, $signature, $serviceAccountKey['private_key'], 'SHA256');
$encodedSignature = base64UrlEncode($signature);

// 组装完整JWT
$jwt = $encodedHeader . '.' . $encodedPayload . '.' . $encodedSignature;

// 发送请求获取访问令牌
$ch = curl_init('https://oauth2.googleapis.com/token');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
    'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
    'assertion' => $jwt
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

$tokenData = json_decode($response, true);
// 拿到可用的access_token
$accessToken = $tokenData['access_token'];
?>

额外注意事项

  • 如果要访问Google Workspace(原G Suite)的用户资源,还需要在Workspace Admin控制台里给服务账号开启域范围授权(Domain-Wide Delegation),把服务账号的client_id添加到授权列表,并指定对应的scope。
  • 访问令牌有效期只有1小时,所以每次调用API前可以检查是否过期,或者干脆每次调用前都生成新的令牌——这个过程很轻量,不会有性能问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:27:38