gpt4 book ai didi

php - Google API OAuth 2.0 身份验证返回 "invalid_grant"- 可能是私钥签名格式问题?

转载 作者:搜寻专家 更新时间:2023-10-31 22:02:29 24 4
gpt4 key购买 nike

我正在尝试连接到需要 OAuth 2.0 身份验证的 Google API。第一步要求我生成一个 JSON Web token (JWT):https://developers.google.com/accounts/docs/OAuth2ServiceAccount?hl=ru#creatingjwt使用以下格式:

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

我按照文档中的所有说明进行操作,但仍然收到“invalid_grant”错误。我怀疑这与最后(签名)部分有关。根据文档:

“计算签名时必须使用JWT头中的签名算法。Google OAuth 2.0授权服务器支持的唯一签名算法是使用SHA-256哈希算法的RSA。这在alg字段中表示为RS256 JWT header 。”

“使用 SHA256withRSA(也称为具有 SHA-256 哈希函数的 RSASSA-PKCS1-V1_5-SIGN)和从 Google Developers Console 获得的私钥对输入的 UTF-8 表示形式进行签名。输出将是一个字节数组。”

“签名必须经过 Base64url 编码。”

我直接从 Google Dev Console 复制私钥(包括“BEGIN PRIVATE KEY”部分)并对其进行 base64 编码。这是我正在使用的代码:

$time = time();
$url = 'https://accounts.google.com/o/oauth2/token';
$assertion = base64_encode('{"alg":"RS256","typ":"JWT"}').'.';
$assertion .= base64_encode('{
"iss":"'.$this->configs['client_id'].'",
"scope":"https://www.googleapis.com/auth/youtube",
"aud":"'.$url.'",
"exp":'.($time+3600).',
"iat":'.$time.'
}').'.';
$assertion .= base64_encode('[-----BEGIN PRIVATE KEY-----privateKeyHere-----END PRIVATE KEY-----\n]');
$headers = array(
'Host: accounts.google.com',
'Content-Type: application/x-www-form-urlencoded'
);
$fields = array(
'grant_type' => urlencode('urn:ietf:params:oauth:grant-type:jwt-bearer'),
'assertion' => urlencode($assertion)
);

$fields_string = '';
foreach($fields as $key => $value) $fields_string .= '&'.$key.'='.$value;
$fields_string = substr($fields_string, 1);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_HEADER, TRUE );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1 );
$result = curl_exec($ch);
curl_close($ch);
var_dump($result);

关于为什么会返回“invalid_grant”错误的任何想法?

最佳答案

你有两个问题:

第一个:PHP 函数 base64_encode 不是 JWT 规范要求的 URL 安全。要获取 Base64Url 字符串,请使用以下函数:

function base64url_encode($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

将您的 base64_encode 调用替换为 base64url_encode

第二个:您永远不会签署您的数据!您只需添加您的私钥,而不是 header 和声明集的签名。使用以下函数:

function sign($input, $private_key)
{
$signature = null;
openssl_sign($input, $signature, $private_key, "SHA256");
return $signature;
}

并替换

$assertion .= base64_encode('{
"iss":"'.$this->configs['client_id'].'",
"scope":"https://www.googleapis.com/auth/youtube",
"aud":"'.$url.'",
"exp":'.($time+3600).',
"iat":'.$time.'
}').'.';
$assertion .= base64_encode('[-----BEGIN PRIVATE KEY-----privateKeyHere-----END PRIVATE KEY-----\n]');

$assertion .= base64_encode('{
"iss":"'.$this->configs['client_id'].'",
"scope":"https://www.googleapis.com/auth/youtube",
"aud":"'.$url.'",
"exp":'.($time+3600).',
"iat":'.$time.'
}');
$assertion .= '.'.base64url_encode(sign($assertion, '[-----BEGIN PRIVATE KEY-----privateKeyHere-----END PRIVATE KEY-----\n]'));

关于php - Google API OAuth 2.0 身份验证返回 "invalid_grant"- 可能是私钥签名格式问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26023391/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com