【发布时间】:2016-09-30 03:41:52
【问题描述】:
我需要为我的服务帐户获取一个访问令牌,该令牌是在我的 google 控制台中创建的,以获取对 google 电子表格服务的私人访问权限!
我的测试用php文件:
<?php
function base64_url_encode($input) {
return strtr(str_replace('=', '', base64_encode($input)), '+/', '-_');
}
header('Content-type: text/plain');
$header = '{"alg":"RS256","typ":"JWT"}';
$payload =
'{
"iss":"[my service account]@[my project name].iam.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/spreadsheets",
"aud":"https://www.googleapis.com/oauth2/v4/token",
"exp":'.(time() + 3600).',
"iat":'.(time()).'
}';
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$private_key = "-----BEGIN PRIVATE KEY-----[my private key from google console json file of my service account]-----END PRIVATE KEY-----\n";
//$rsa->setPassword('password');
$rsa->loadKey($private_key); // private key
$plaintext = base64_url_encode($header).'.'.base64_url_encode($payload);
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$signature = $rsa->sign($plaintext);
//$rsa->loadKey($rsa->getPublicKey()); // public key
//echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
$jwt = base64_url_encode($header).'.'.base64_url_encode($payload).'.'.base64_url_encode($signature);
$query = http_build_query(Array('grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt));
//echo $query;
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => $query
)
);
$context = stream_context_create($options);
$access_token = file_get_contents('https://www.googleapis.com/oauth2/v4/token', false, $context);
?>
php 输出:
file_get_contents(https://www.googleapis.com/oauth2/v4/token) [<a href='function.file-get-contents'>function.file-get-contents</a>]: failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
如果我在 wfetch 中运行相同的查询(来自 php 脚本的“$query”变量):
HTTP/1.1 400 Bad Request\r\n
{\n
"error": "invalid_grant",\n
"error_description": "Invalid JWT Signature."\n
}\n
附:我的 php 版本是 PHP 5.2(不支持命名空间),也使用了 phpseclib1.0.3。
附言尝试将 RS256 更改为 HS256,谷歌仍然响应 400 - 无效的 JWT 签名,但如果更改为不存在的 XX256(例如)-> 谷歌响应 500 - 错误:internal_failure。所以我想可能是google也支持HS256。如果这是真的 - 我可以使用更简单的 HS256 方法。我发现了这个:https://github.com/progrium/php-jwt/blob/master/JWT.php
【问题讨论】:
-
您是否尝试过在 Google 官方 php 客户端库中进行挖掘,看看他们是如何做到的? github.com/google/google-api-php-client/tree/v1-master
-
这是个好建议!
-
我曾尝试让服务帐户手动工作,但从未让它工作。总是最终使用客户端库。祝你好运:)
-
invalid_grant 通常是时间问题,请确保您使用的时间正确。
标签: php google-oauth google-spreadsheet-api