如何将 oAuth 与 Guzzle 5(或者,更好,与 Guzzle 6)一起使用

2021-12-31 00:00:00 oauth curl php guzzle

我正在尝试使用 Guzzle 5 连接到 WooCommerce API(Guzzle 6 似乎没有 oAuth 选项 o.O).Woocommerce 需要 oAuth 身份验证方法才能工作.

I'm trying to connect to the WooCommerce API using Guzzle 5 (Guzzle 6 seems not has oAuth options o.O). Woocommerce requires the oAuth authentication method to work.

这是我正在使用的代码:

This is the code I'm using:

<?php

/**
 * Example of usage of Guzzle 5 to get information
 * from a WooCommerce Store.
 */

require('../vendor/autoload.php');

use GuzzleHttpClient;
use GuzzleHttpSubscriberOauthOauth1;
use GuzzleHttpExceptionRequestException;

$consumer_key = 'my_consumer_key'; // Add your own Consumer Key here
$consumer_secret = 'my_consumer_secret'; // Add your own Consumer Secret here
$store_url = 'http://example.com'; // Add the home URL to the store you want to connect to here
$api_path = '/wc-api/v2/';
$api_end_point = [
    'root' => '',
    'orders' => 'orders'
    ];

$base_uri = $store_url . $api_path;

$client = new Client([
    'base_url' => $base_uri,
    'defaults' => ['auth' => 'oauth']
    ]);

$oauth = new Oauth1([
    'consumer_key'    => $consumer_key,
    'consumer_secret' => $consumer_secret,
    'request_method'  => 'query'
]);

$client->getEmitter()->attach($oauth);

try
{
    $res = $client->get($api_end_point['orders']);
}
catch (RequestException $e)
{
    $res = $e;

    if ($e->hasResponse())
    {
        $res = $e->getResponse();
    }
}

print_r($res);

echo $res->getStatusCode();
// "200"
echo $res->getHeader('content-type');
// 'application/json; charset=utf8'
echo $res->getBody();
// {"type":"User"...'

此代码返回一个

woocommerce_api_authentication_error:签名无效 - 已提供签名不匹配

woocommerce_api_authentication_error: Invalid Signature - provided signature does not match

使用纯 curl 函数(使用 这个包,其中我已经在这里) 中添加了一些功能,相反,它有效我得到了我想要的所有订单和其他数据.

Using pure curl functions (using this package in which I've put some functions I found here), instead, it works and I get all orders and other data I want.

其他一些细节

为了使用 Guzzle 5 和 oAuth,我使用了这些 composer 包:

To use Guzzle 5 and oAuth I use the those composer packages:

"require": {
    "guzzlehttp/guzzle": "~5.0"
},
"require-dev": {
    "guzzlehttp/oauth-subscriber": "~0.2",
},

似乎在创建签名时有些不同:由 我到目前为止使用的库 可以工作,但是由 oAuth 插件创建的库 (使用 Guzzle 的方法 getSignature()) 没有,我不太习惯使用 oAuth 来查找错误.有人可以帮我找出问题所在吗?

It seems there are some things that are different in creating the signature: the one created by the library I've used until now works, but the one created by the oAuth plugin (using the method getSignature()) for Guzzle doesn't and I'm not so used to use oAuth to find the error. Is there someone who can help me identify the problem?

推荐答案

更新@Aerendir 答案

在他的拉取请求中,@Aerendir 写道:

In his pull request, @Aerendir wrote:

就我而言,我在尝试连接到WooCommerce API 版本 2 但该版本的 API 没有实现正确的 OAuth 核心 1.0a 规范.事实上,他们解决了这个问题API 的第 3 版.查看 V3 和更旧版本之间的差异版本.

In my case, I did the editing as I were trying to connect to the WooCommerce API version 2 but that version of the API didn't implement correctly the OAuth Core 1.0a spec. In fact, they fixed this issue in the version 3 of the API. See Differences between V3 and older versions.

来源:https://github.com/guzzle/oauth-订阅者/拉/42#issuecomment-185631670

所以,为了让他的回答正常工作,我们需要使用 wc-api/v3/ 而不是 wc-api/v2/>.

So, to make his answer work properly, we need to use wc-api/v3/ instead of wc-api/v2/.

以下代码使用 Guzzle 6、oauth 和 WooCommerce api v3:

The following code, works using Guzzle 6, oauth and WooCommerce api v3:

use GuzzleHttpClient,
    GuzzleHttpHandlerStack,
    GuzzleHttpHandlerCurlHandler,
    GuzzleHttpSubscriberOauthOauth1;

$url = 'http://localhost/WooCommerce/';
$api = 'wc-api/v3/';
$endpoint = 'orders';
$consumer_key = 'ck_999ffa6b1be3f38058ed83e5786ac133e8c0bc60';
$consumer_secret = 'cs_8f6c96c56a7281203c2ff35d71e5c4f9b70e9704';

$handler = new CurlHandler();
$stack = HandlerStack::create($handler);

$middleware = new Oauth1([
    'consumer_key'    => $consumer_key,
    'consumer_secret' => $consumer_secret,
    'token_secret'    => '',
    'token'           => '',
    'request_method' => Oauth1::REQUEST_METHOD_QUERY,
    'signature_method' => Oauth1::SIGNATURE_METHOD_HMAC
]);
$stack->push($middleware);

$client = new Client([
    'base_uri' => $url . $api,
    'handler' => $stack
]);

$response = $client->get( $endpoint, [ 'auth' => 'oauth' ] );
echo $response->getStatusCode() . '<br>';
echo $response->getHeaderLine('content-type') . '<br>';
echo $response->getBody();

相关文章