【问题标题】:Trouble with JWT and PHPJWT 和 PHP 的问题
【发布时间】: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


【解决方案1】:

这是一个完整的 openssl/curl 示例:

<?php

$url = "https://www.googleapis.com/oauth2/v4/token";
$scope = 'https://www.googleapis.com/auth/spreadsheets';

$client_id = 'xxxxx@developer.gserviceaccount.com';
$p12 = 'google-api-xxxxx.p12';
$p12pwd = 'notasecret';

function base64_url_encode($input) {
    return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}

$iat = time();
$jwt_data = array(
    'iss' => $client_id,
    'aud' => $url,
    'scope' => $scope,
    'exp' => $iat + 3600,
    'iat' => $iat,
);

openssl_pkcs12_read(file_get_contents($p12), $certs, $p12pwd);
$header = array('typ' => 'JWT', 'alg' => 'RS256');
$signing_input = base64_url_encode(json_encode($header)) . '.' . base64_url_encode(json_encode($jwt_data));
openssl_sign($signing_input, $signature, $certs['pkey'], 'SHA256');
$jwt = $signing_input . '.' . base64_url_encode($signature);

$data = array(
    "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "assertion" => $jwt
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch) ;
echo $response;
?>

【讨论】:

  • 哇哇哇哇哇哇哇哇哇!!!!!!呜呜呜!!!有用!!!!我花了大约 2 天时间寻找访问令牌。现在它起作用了!!!!非常感谢!!!!附:顺便说一句,它只适用于 PHP 5.4+,因为我发现旧 php 版本中的 openssl 不支持 SHA256 方法。我的第一次尝试是在 5.2 上失败了,但后来我在另一台服务器上尝试了 5.4 并且它可以工作!!!!!! php.net/manual/en/openssl.signature-algos.php
  • 嗨,这些是什么$p12 = 'google-api-xxxxx.p12';$p12pwd = 'notasecret';
猜你喜欢
  • 2016-04-04
  • 2019-06-07
  • 1970-01-01
  • 2023-03-27
  • 2020-05-04
  • 2021-01-15
  • 1970-01-01
  • 2020-11-30
  • 2017-07-20
相关资源
最近更新 更多