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的“计算签名”部分

4

2 回答 2

0

401 表示请求未经授权。您需要在请求中发送Authorization标头,这取决于授权需要哪种身份验证令牌(应该在 api 文档中)。使用 cURL 在 PHP 中设置标头(例如不记名令牌):

$header = array(
    'Authorization: Bearer <insert-token-here>'
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
于 2019-07-17T08:45:04.210 回答
0

好的,我已经设法解决了 2 天以上的问题,并找到了解决方案。我将其发布在这里是为了帮助将来可能会遇到此问题的其他人。这是为了使用 php 和 google 服务帐户来使用 JWT 获取令牌,然后拨打电话以从您的 Google Merchant Shopping 帐户中获取所有产品。

$merchantid = xxxxxxxxx; //this is a 9 digit code found in top left of Merchant Center
$email = 'xxxxxxxxxxx@merchant-center-xxxxxxxxxxxx.iam.gserviceaccount.com'; //this is the email address assigned to the service account
$privatekey = "-----BEGIN PRIVATE KEY-----\nXXXXXapprox 6 lines long key from json fileXXXXXX\n-----END PRIVATE KEY-----\n"; //this is the long key that you download within the json file at the end of the service account setup
$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' => $email, 
'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));
$binary_signature = "";
$algo = "SHA256";
openssl_sign($base64UrlHeader.".".$base64UrlClaimSet, $binary_signature, $privatekey, $algo);
$jwtSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($binary_signature));
$jwt = $base64UrlHeader . "." . $base64UrlClaimSet . "." . $jwtSignature;
$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);
$accesstoken = substr($data, strpos($data, 'access_token') + 16);
$arr = explode('"',trim($accesstoken));
$accesstoken = $arr[0]; 
$url = "https://www.googleapis.com/content/v2/".$merchantid."/products";
$header = array(
    'Authorization: Bearer '.$accesstoken
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
echo "<br/><br/>data: ".$data;
于 2019-07-18T14:57:56.637 回答