php - 从 API 获取产品数据的初始调用不起作用 - 无法确定如何将 OAuth 2.0 连接到调用
问题描述
我正在尝试连接到 Google Shopping Products API 以创建一些新产品项目。在我执行更复杂的任务之前,我只是尝试连接以获取现有产品的列表。
我已经在 Google API 控制台中设置了一个服务帐户并下载了 json 密钥文件。我已将文件保存到服务器。然后,我从 Google 的文档中提取了所有示例,并尝试将它们拼凑在一起。
变量注释:
$KEY_FILE_LOCATION - 这是 json 服务帐户密钥文件的位置。
$merchantid - 这是我的 Google Merchant Center 的商家 ID
代码:
$client->setAuthConfig($KEY_FILE_LOCATION);
$client->setApplicationName('Merchant Centre');
$client->setScopes('https://www.googleapis.com/auth/content');
echo "<br/><br/>client: ".json_encode($client);
$url = "https://www.googleapis.com/content/v2/".$merchantid."/products";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
echo "<br/><br/>data: ".$data;
我遇到的问题是如何将身份验证连接到实际的谷歌购物电话。与 content/v2/merchantid/products 调用的连接返回此响应:
{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } }
那么如何将 oauth 2.0 身份验证服务帐户 json 连接到实际调用。我在文档或在线中找不到任何关于您如何将这两件事实际连接在一起的内容。我已与其他 Google API 集成,但我所拥有的代码都没有提供实现此功能的清晰示例。
编辑:通过进一步了解文档,我设法制定了一个可行的流程。我需要使用 JWT 来获取调用 API 的令牌 - 下面的代码用于访问令牌,但在最后一部分仍然失败。此调用的响应是 { "error": "invalid_grant", "error_description": "Invalid JWT Signature." }。JWT 的签名部分是唯一看起来与 Google 给出的示例不同的部分 - 我的代码输出 43 个字符的签名,而 googles 明显更长。
$header = json_encode(['alg' => 'RS256', 'typ' => 'JWT']);
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
$iat = strtotime("now");
$exp = strtotime("+1 hour");
$currenttime = date("H:i:s");
$claimset = json_encode(['iss' => 'REDACTED',
'scope' => 'https://www.googleapis.com/auth/content',
'aud' => 'https://www.googleapis.com/oauth2/v4/token',
'exp' => $exp,
'iat' => $iat]);
$base64UrlClaimSet = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($claimset));
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlClaimSet, $privatekey, true);
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
$jwt = $base64UrlHeader . "." . $base64UrlClaimSet . "." . $base64UrlSignature;
$url = "https://www.googleapis.com/oauth2/v4/token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=".$jwt);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
echo "<br/><br/>data: ".$data;
我正在尝试遵循此https://developers.google.com/identity/protocols/OAuth2ServiceAccount的“计算签名”部分
解决方案
401 表示请求未经授权。您需要在请求中发送Authorization
标头,这取决于授权需要哪种身份验证令牌(应该在 api 文档中)。使用 cURL 在 PHP 中设置标头(例如不记名令牌):
$header = array(
'Authorization: Bearer <insert-token-here>'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
推荐阅读
- java - Graphql SPQR 自定义对象序列化/反序列化
- sql - SQL查询以查找分组值的所有组合
- javascript - 访问被 CORS 策略阻止的脚本
- android - UdpClient.Close() 在 Unity 中抛出 android.os.DeadObjectException(使用 IL2CPP)
- sql - 需要创建程序以查找具有大多数 emps 的部门
- python - List claims to be empty but still contains an object
- javascript - 如果删除表行,.submit() 不起作用
- python-3.x - 运行没有相对导入的python项目
- ios - 使用其他属性初始化 @Binding 时的问题
- r - 在闪亮中,使用仪表板加,如何控制小部件样式?