【问题标题】:How do I authenticate a POST to the Discogs API with PHP / cURL如何使用 PHP / cURL 对 Discogs API 的 POST 进行身份验证
【发布时间】:2016-04-24 01:59:13
【问题描述】:

我已成功使用此处的示例https://gist.github.com/tonefolder/44191a29454f9059c7e6 来验证用户并存储 oauth_token 和 oauth_token_secret。然后我可以使用 cURL 发出经过身份验证的 GET 请求。

我不知道如何发出经过身份验证的 POST 请求。

我尝试过以这种方式使用已签名 oauthObject 中的 $result['header']:

$discogs_username = "'XXXX'";

$result = mysql_query("SELECT * FROM discogs WHERE username = $discogs_username;", $link);
if (mysql_num_rows($result)) {
    $discogs_details = mysql_fetch_array($result, MYSQL_ASSOC);
}


$signatures = array(
    'consumer_key'     => 'MyKey',
    'shared_secret'    => 'MySecret',
  'oauth_token'    => $discogs_details['oauth_token'],
  'oauth_token_secret'    => $discogs_details['oauth_token_secret']
);


$jsonquery = json_encode(array(
        'release_id' => '7608939',
        'price' => '18.00',
        'condition' => 'Mint',
        'sleeve_condition' => 'Mint',
        'status' => 'For Sale'
    )
);


$result = $oauthObject->sign(array(
        'path'      => $scope.'/marketplace/listings',
        'signatures'=> $signatures
    )
);


$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'MyDiscogsClient/0.1 +http://me.com');
curl_setopt($ch, CURLOPT_URL, $result['signed_url']);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Authorization:' . $result['header'])); 
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonquery);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = json_decode(curl_exec($ch), true);
curl_close($ch);

但我得到'[message] => 您必须进行身份验证才能访问此资源。'

我不确定我是否正确地执行了 CURLOPT_POSTFIELDS 部分,但是一旦我真正能够发送经过身份验证的 POST,我就可以弄清楚!抱歉,如果这还有更多错误 - 我不经常使用 cURL!

【问题讨论】:

  • 我也在 Discogs API 论坛上问过这个问题link,但没有人回复。我在这里要求的东西真的很晦涩吗?
  • 我看到 discogs 在这里有很好的 api 文档:discogs.com/developers 并且在快速入门中:discogs.com/developers/#page:home,header:home-quickstart,存在 PHP 客户端 API 库:github.com/ricbra/php-discogs-api,您可以尝试使用它进行通信与他们一起创造服装方法
  • 谢谢,但该客户端似乎只支持 GET 请求而不是 POST 请求
  • 您只发布了部分代码,或者这是您正在使用的完整代码?
  • 没有太多多余的东西,只是创建了签名数组,我会编辑它。

标签: php authentication curl oauth discogs-api


【解决方案1】:

背景

在复制了您的所有步骤并摆弄了一下之后,我发现了以下内容。作为一个侧节点,我假设$scope变量只包含API url,即https://api.discogs.com

事实证明,签署 OAuth 请求还需要知道您将使用的正确请求方法。你可以通过var_dump()ing $result 找到你从sign() 电话中得到的信息:

array(5) {
/// ... snip ...
    'sbs' =>
  string(269) "GET&https%3A%2F%2Fapi.discogs.com%2Fmarketplace%2Flistings&oauth_consumer_key%XXXXX%26oauth_nonce%3DMOtWK%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1453937109%26oauth_token%XXXXX%26oauth_version%3D1.0"
}

所以我深入研究了您正在使用的"OAuthSimple" library 的代码,结果发现您可以在名为“action”的索引下传递该方法。

解决方案

根据调查结果,您将不得不改变这一点:

$result = $oauthObject->sign(
    array(
        'path' => $scope . '/marketplace/listings',
        'signatures' => $signatures,
    )
);

到这里:

$result = $oauthObject->sign(
    array(
        'path' => $scope . '/marketplace/listings',
        'signatures' => $signatures,
        'action' => 'POST',
    )
);

旁注

我实际上尝试了该解决方案,并且能够通过 API 创建列表。我必须做的唯一其他更改是他们的 API 不允许条件和 sleeve_condition 值Mint,因此您实际上必须使用 Mint (M)

另外,我一开始收到一个错误,提示我必须完成“卖家设置”。所以你可能想在你的应用程序中捕捉到这种情况。

进一步的想法

正如您在原始帖子的 cmets 中提到的,您假设 suggested library 也只允许 GET 请求。然而,作为you can see here,它只返回一个Guzzle Client,因此通过它触发POST 请求根本不成问题,实际上使用它可能会为您节省很多痛苦。但是我没有尝试过,所以,就像我想的那样。

希望有帮助:)

【讨论】:

  • 谢谢@ArSen - 最后答案很简单。希望这对其他人也有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多