如何使用 PHP / cURL 向 Discogs API 验证 POST
How do I authenticate a POST to the Discogs API with PHP / cURL
我已成功使用这里的示例 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);
但我收到“[消息] => 您必须进行身份验证才能访问此资源。”
我不确定我是否正确地完成了 CURLOPT_POSTFIELDS 部分,但是一旦我真正能够发送经过身份验证的 POST,我就可以弄明白了!抱歉,如果还有更多错误 - 我不经常使用 cURL!
背景
在重现您的所有步骤并稍微摆弄之后,我发现了以下内容。作为侧节点,我假设 $scope
变量只包含 API url,即 https://api.discogs.com
.
事实证明,签署 OAuth 请求也需要知道您将要使用的正确请求方法。您可以通过 var_dump()
ing 您从 sign()
调用中获得的 $result
发现:
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 创建列表。我必须做的唯一其他更改是条件和 sleeve_condition 值 Mint
不允许它们 API 所以你实际上必须使用 Mint (M)
.
另外,一开始我收到一个错误,说我必须完成我的 "seller settings"。所以你可能想在你的应用程序中捕捉到这种情况。
进一步思考
正如您在对原始 post 的评论中提到的那样,您假设 suggested library just allows GET requests also. However, as you can see here, it just returns a Guzzle Client,因此通过此触发 POST 请求根本不成问题,实际上使用它可能会为您省去很多痛苦。不过我没试过,所以,和想的一样。
希望对您有所帮助:)
我已成功使用这里的示例 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);
但我收到“[消息] => 您必须进行身份验证才能访问此资源。”
我不确定我是否正确地完成了 CURLOPT_POSTFIELDS 部分,但是一旦我真正能够发送经过身份验证的 POST,我就可以弄明白了!抱歉,如果还有更多错误 - 我不经常使用 cURL!
背景
在重现您的所有步骤并稍微摆弄之后,我发现了以下内容。作为侧节点,我假设 $scope
变量只包含 API url,即 https://api.discogs.com
.
事实证明,签署 OAuth 请求也需要知道您将要使用的正确请求方法。您可以通过 var_dump()
ing 您从 sign()
调用中获得的 $result
发现:
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 创建列表。我必须做的唯一其他更改是条件和 sleeve_condition 值 Mint
不允许它们 API 所以你实际上必须使用 Mint (M)
.
另外,一开始我收到一个错误,说我必须完成我的 "seller settings"。所以你可能想在你的应用程序中捕捉到这种情况。
进一步思考
正如您在对原始 post 的评论中提到的那样,您假设 suggested library just allows GET requests also. However, as you can see here, it just returns a Guzzle Client,因此通过此触发 POST 请求根本不成问题,实际上使用它可能会为您省去很多痛苦。不过我没试过,所以,和想的一样。
希望对您有所帮助:)