【发布时间】:2019-09-12 08:33:21
【问题描述】:
我正在关注documentation 的服务器到服务器 OAuth2 流程(创建我自己的 JWT,而不是使用库)。
我创建了一个具有正确权限的服务帐号,可以上传到我的存储分区。我成功地从https://www.googleapis.com/oauth2/v4/token 获得了一个范围为https://www.googleapis.com/auth/devstorage.full_control 的access_token,如文档中所述并使用我的服务帐户的电子邮件。
当我按照描述在我的 POST 请求中添加 access_token 作为标头时,我收到以下错误消息:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Anonymous caller does not have storage.objects.create access to bucket/object.",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Anonymous caller does not have storage.objects.create access to bucket/object."
}
}
这是我的 JWT 结构:
$googleJson = json_decode(file_get_contents('/app/config/jwt/google.json'), true);
$time = time();
$headers = [
'alg' => 'RS256',
'typ' => 'JWT'
];
$payload = [
'iss' => $googleJson['client_email'],
'scope' => 'https://www.googleapis.com/auth/devstorage.full_control'
'aud' => 'https://www.googleapis.com/oauth2/v4/token',
'exp' => $time + 120,
'iat' => $time
];
$jwt = JWTService::create($headers, $payload, $googleJson['private_key']);
return http_build_query([
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
]);
我在这里缺少什么?显然,这个 access_token 应该对我的请求进行身份验证,但是将请求标记为 Anonymous caller 的错误消息让我怀疑我根本没有经过身份验证。
这是我用来创建 JWT 的函数:
public static function create(array $headers, array $payload, string $privateKey): string
{
$headers = json_encode($headers);
$payload = json_encode($payload);
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($headers));
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
openssl_sign($base64UrlHeader . '.' . $base64UrlPayload, $signature, $privateKey, 'sha256');
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
return $base64UrlHeader . '.' . $base64UrlPayload . '.' . $base64UrlSignature;
}
更新:当我将访问令牌作为&access_token=<access_token> 之类的查询参数包含在内时,它可以工作,所以由于某种原因,访问令牌不能作为标头工作,我不知道为什么
Update2:我将标题设置为键值数组,例如
[
Authorization => Bearer <token>
]
哎呀,对不起大家
【问题讨论】:
-
您能否详细说明如何计算签名?调试时,建议在iat之后设置过期时间3600s,同时对grant_type进行URL编码:
urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer。 -
此错误表示您没有正确包含令牌或标头丢失/不正确。
Authorization: bearer <TOKEN> -
@alextru 谢谢,我现在就试试。我已经用我用来计算签名的函数更新了我的帖子。
http_build_query函数对 grant_type 进行编码,我认为因为我成功获取了 access_token,所以我的 JWT 没有问题,但我可能错了 -
@JohnHanley 我将令牌作为标头包含在内:
Authorization: Bearer <access_token> -
@alextru @JohnHanley 更新:当我将访问令牌作为
&access_token=<access_token>之类的查询参数包含在内时,它可以工作,因此由于某种原因,访问令牌不能作为标头工作,我不能找出原因
标签: google-cloud-platform google-cloud-storage