GSC_Client和oAuth2访问

Gor*_*onM 5 php google-api oauth-2.0 google-shopping-api

我正在开始编写一个PHP脚本,该脚本将作为cron作业运行,并通过Google Shopping API定期更新产品列表.

我下载了PHP的GSC客户端库,我正在尝试使用Google Shopping API文档来获取令牌.然而,感觉就像在文档中某处有关于如何在生成URL后实际请求令牌的步骤.

到目前为止,这是我的代码:

require ("./lib/shoppingclient/GShoppingContent.php");

const G_MERCHANT_ID     = '**********';
const G_CLIENT_ID       = '**********';
const G_CLIENT_SECRET   = '**********';

$obj_client = new GSC_Client (G_MERCHANT_ID);

// Obtain an OAuth2 token to access the API with
$obj_token  = new GSC_OAuth2Token (G_CLIENT_ID, G_CLIENT_SECRET, USER_AGENT);

$str_url    = $obj_token -> generateAuthorizeUrl ('urn:ietf:wg:oauth:2.0:oob');
echo ($str_url . PHP_EOL);

/* @var $obj_response _GSC_Response */
$obj_response = $obj_token -> makeAuthenticatedRequest (curl_init ($str_url));
echo ($obj_response);
Run Code Online (Sandbox Code Playgroud)

当我从命令行运行上面的命令时,我得到:

https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=blah-blah-blah-etc-etc-etc ...

<HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>

Fatal error: Uncaught exception 'GSC_TokenError' with message 'invalid_request' in /var/samba/GoogleShoppingTest/lib/shoppingclient/GShoppingContent.php on line 624

GSC_TokenError: invalid_request in /var/samba/GoogleShoppingTest/lib/shoppingclient/GShoppingContent.php on line 624

Call Stack:
    0.0002     321888   1. {main}() /var/samba/GoogleShoppingTest/logintest.php:0
    0.0065    1446196   2. GSC_OAuth2Token->makeAuthenticatedRequest() /var/samba/GoogleShoppingTest/logintest.php:19
    0.2797    1446684   3. GSC_OAuth2Token->refresh() /var/samba/GoogleShoppingTest/lib/shoppingclient/GShoppingContent.php:722
    0.3992    1448152   4. GSC_OAuth2Token::raiseFromJson() /var/samba/GoogleShoppingTest/lib/shoppingclient/GShoppingContent.php:565
Run Code Online (Sandbox Code Playgroud)

我相当肯定初始化一个CURL对象不应该是必要的,但我无法弄清楚我是如何从生成的URL获得解析的实际响应.

如果我访问generateAuthorizeUrl()生成的URL,我会得到一个带有按钮的页面,要求我授予权限.如果我这样做,我会得到一个页面,上面有一个令牌,据我所知是有效的.

但是,这是一个cron脚本,显然无法要求用户单击按钮并确认他们想要授予权限,所以很明显我会偏离某个地方.

有没有人设法让GSC_Client在完全自动的脚本中使用OAuth?如果是这样,我在这里做错了什么?

更新:对于此应用程序,我已将API类型配置为"已安装的应用程序",这似乎是此应用程序的正确API类型.这意味着我为脚本提供了共享密钥并使用https://localhost或urn:ietf:wg:oauth:2.0:oob作为URL.

更新2:我不认为GSC客户端的支持库支持服务器到服务器方案.进一步的研究表明,如果我想使用私钥验证方法,我需要Google API客户端库.

这是我到目前为止编写的代码:

require ("./lib/google/oauthclient/Google_Client.php");
require ("./lib/google/shoppingclient/GShoppingContent.php");

const G_MERCHANT_ID     = '********';
const G_CLIENT_ID       = '********';
const G_CLIENT_EMAIL    = '********';
const G_CLIENT_KEY_PATH = '/path/to/the/privatekey.p12';
const G_CLIENT_KEY_PW   = 'notasecret';

$obj_client_auth  = new Google_Client ();
$obj_client_auth -> setApplicationName ('test');
$obj_client_auth -> setClientId (G_CLIENT_ID);
$obj_client_auth -> setAssertionCredentials (new Google_AssertionCredentials (
        G_CLIENT_EMAIL, 
        array (OAUTH_SCOPE), 
        file_get_contents (G_CLIENT_KEY_PATH), 
        G_CLIENT_KEY_PW));

$obj_client_auth -> getAuth () -> refreshTokenWithAssertion ();

// Get a token
$obj_token  = json_decode ($obj_client_auth -> getAccessToken ());
print_r ($obj_token);
Run Code Online (Sandbox Code Playgroud)

当我运行上面的代码时,我得到类似以下内容的回报:

stdClass Object
(
    [access_token] => ya29.AHES6ZRJohl2AfbQCKbFxNlagSqLGcjHwiylqASX1ygmwg
    [expires_in] => 3600
    [created] => 1359123809
)
Run Code Online (Sandbox Code Playgroud)

我猜这是一个有效的访问令牌响应.

但是,我还没有弄清楚如何将返回的令牌与GSC_Client库一起使用.虽然我知道这些库都来自Google,但我得到的不同印象是它们是由不同的团队开发的,这些团队彼此之间几乎没有任何关系,最终的结果是这些库不是交叉兼容的.如果有人知道该怎么做,我会很感激您的任何建议.

更新3

我已经设法使用oAuth库实际从Google提取数据,但它来自Search API进行购物.我需要使用Content API来处理产品列表以进行购物.似乎没有为oAuth库提供的类,即使在contrib目录中也是如此!

仅供参考,这是执行搜索API请求的代码(减去常量):

$obj_client_auth  = new Google_Client ();
$obj_client_auth -> setApplicationName ('test');
$obj_client_auth -> setClientId (G_CLIENT_ID);
$obj_client_auth -> setAssertionCredentials (new Google_AssertionCredentials (
        G_CLIENT_EMAIL, 
        array (
            //'https://www.googleapis.com/auth/structuredcontent',
            'https://www.googleapis.com/auth/shoppingapi'
            ), 
        file_get_contents (G_CLIENT_KEY_PATH), 
        G_CLIENT_KEY_PW));

$obj_client_api   = new Google_ShoppingService ($obj_client_auth);

$arr_results = $obj_client_api -> products -> listProducts ('public', array (
   'country'   => 'GB',
   'q'         => '"mp3 player" | ipod', 
   'rankBy'    => 'relevancy'
));

print_r ($arr_results);
Run Code Online (Sandbox Code Playgroud)

Gor*_*onM 1

看起来 GSC_client 库与其自己的 OAuth2 实现耦合得太紧密,以至于 Google_Client 库无法轻松集成到其中,而无需进行大量的重构工作。此外,GSC_Client 的 OAuth2 实现与客户端秘密概念以及重定向到同意页面的耦合过于紧密,因此我无法编写一个将 Google_Client 实现包装为替代品的实现。

幸运的是,我们有一个内部开发的用于与 Google API 接口的代码库,并且与其身份验证系统的耦合不太紧密。经过一些工作,可以向其中添加一个包装 Google_Client 的新身份验证模块。

然而,似乎没有关于如何让 Google 的 GSC_Client 与 Google_Client 一起工作的答案,所以我仍在寻找更好的答案。