如何在Guzzle 5中使用oAuth(或者更好,使用Guzzle 6)

时间:2015-07-16 13:46:20

标签: php curl oauth guzzle

我正在尝试使用Guzzle 5连接到WooCommerce API(Guzzle 6似乎没有oAuth选项o.O)。 Woocommerce requires the oAuth authentication method可以工作。

这是我正在使用的代码:

<?php

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

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

use GuzzleHttp\Client;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
use GuzzleHttp\Exception\RequestException;

$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:签名无效 - 已提供   签名不匹配

使用纯卷曲函数(使用this package,其中我已经放置了一些我找到的函数here),相反,它可以工作,我得到了我想要的所有订单和其他数据。

其他一些细节

使用Guzzle 5和oAuth我使用那些作曲家包:

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

在创建签名时似乎有一些不同的东西:由the library I've used until now创建的那个有效,但是由ozzle开头创建的那个(using the method getSignature())对于Guzzle不起作用我不习惯使用oAuth来查找错误。有人可以帮我识别问题吗?

2 个答案:

答案 0 :(得分:4)

更新@Aerendir回答

在他的拉动请求中,@ Alrendir写道:

  

在我的情况下,我做了编辑,因为我试图连接到   WooCommerce API版本2但该API的版本没有实现   正确的OAuth Core 1.0a规范。事实上,他们已经解决了这个问题   API的第3版。请参阅V3和较旧版本之间的差异   版本

     

来源:https://github.com/guzzle/oauth-subscriber/pull/42#issuecomment-185631670

因此,为了使他的答案正常运行,我们需要使用 wc-api / v3 / 而不是 wc-api / v2 /

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

use GuzzleHttp\Client,
    GuzzleHttp\HandlerStack,
    GuzzleHttp\Handler\CurlHandler,
    GuzzleHttp\Subscriber\Oauth\Oauth1;

$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();

答案 1 :(得分:2)

现在插件OauthSubscriber仅适用于Guzzle 6。 再次测试,我发现了这个错误:它在方法signUsingHmacSha1()中无论如何都会在字符串中添加一个umpersand(&amp;)来签名,这会导致WooCommerce出错。

我在GitHub上opened a issuesent a pull request来修复错误。

使用Guzzle 6连接到 WooCommerce API V2的正确方法(一旦修复了错误!处理您连接的WooCommerce API的版本:API v3仍然没有& #39; t work!)是这样的:

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Subscriber\Oauth\Oauth1;

$options = array(
    // Add the home URL to the store you want to connect to here (without the end / )
    'remoteUrl'          => 'http://example.com/',
    // Add your own Consumer Key here
    'remoteConsumerKey'  => 'ck_4rdyourConsumerKey8ik',
    // Add your own Secret Key here
    'remoteSecretKey'    => 'cs_738youconsumersecret94i',
    // Add the endpoint base path
    'remoteApiPath' => 'wc-api/v2/',
);

$remoteApiUrl = $options['remoteUrl'] . $options['remoteApiPath'];
$endpoint = 'orders';

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

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

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

$res = $client->get($endpoint, ['auth' => 'oauth');

据说,此连接仅适用于WooCommerce API的第2版。

我正在调查以了解V3无法正常工作的原因。