问题描述
我正在尝试使用PHP 7.4在Web服务器上向Twitter发出Twitter verify_credentials请求。
仅当我在邮递员中设置OAuth1.0请求标头设置时,才能获得http 200代码和正确的响应:
使用相同数据进行请求的任何其他方式都会返回401 http状态代码错误
{"errors":[{"code":32,"message":"Could not authenticate you."}
我需要在GUZZLE的PHP CURL或其他http请求客户端代码中转换此Postman设置。但是,当我从Postman导入CURL示例时,它总是抛出相同的401异常。所以我尝试了不同的方法:
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL => "https://api.twitter.com/1.1/account/verify_credentials.json",CURLOPT_RETURNTRANSFER => true,CURLOPT_ENCODING => "",CURLOPT_MAXREDirs => 10,CURLOPT_TIMEOUT => 0,CURLOPT_FOLLOWLOCATION => true,CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,CURLOPT_CUSTomrEQUEST => "GET",CURLOPT_HTTPHEADER => array(
"Authorization: OAuth oauth_consumer_key=\"oauth_consumer_key\",oauth_token=\"oauth_token\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1605187800\",oauth_nonce=\"hmkiezWh6xqlfJYpK55rDVgcGydQkuBH\",oauth_version=\"1.0\",oauth_callback=\"http%3A%2F%2Fmyurl.com\",oauth_signature=\"signature\""
),));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
或另一个:
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
$client = new Client;
$headers =[
'Authorization' => 'OAuth oauth_consumer_key="oauth_consumer_key",oauth_token="oauth_token",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1605187800",oauth_nonce="hmkiezWh6xqlfJYpK55rDVgcGydQkuBH",oauth_version="1.0",oauth_callback="http%3A%2F%2Furl.com",oauth_signature="SdB60Nr6AhJzOdAIWlW%2FwdmeJM4%3D"',];
$request = new Request('GET','https://api.twitter.com/1.1/account/verify_credentials.json',$headers);
$client->send($request);
$response = $client->getResponse();
echo $response->getBody();
或者那样:
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-PHP/
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,'https://api.twitter.com/1.1/account/verify_credentials.json');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CUSTomrEQUEST,'GET');
$headers = array();
$headers[] = 'Authorization: OAuth oauth_consumer_key=\"oauth_consumer_key\",oauth_callback=\"http%3A%2F%2Furl.com\",oauth_signature=\"H%2FpmcdPUnlMD8RN42RpfBs%2Fs7Cc%3D\"';
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
每次都会出现401错误。因此,如何在PHP CURL中设置所有OAuth1.0属性,以使用在Postman中可用的相同标头重现相同的请求?
P.S。我已经尝试过abraham / twitteroauth,laravel / socialite和其他解决方案,结果相同
解决方法
如果您使用的是guzzle 6或更高版本,则可以直接使用由guzzle本身创建的guzzlehttp/oauth-subscriber
程序包来处理它(否则这是一个漫长的过程),
将以下内容添加到您的composer.json中:
{
"require": {
"guzzlehttp/oauth-subscriber": "0.4.*"
}
}
我从他们的文档中获取了示例,
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
$stack = HandlerStack::create();
$middleware = new Oauth1([
'consumer_key' => 'my_key','consumer_secret' => 'my_secret','token' => 'my_token','token_secret' => 'my_token_secret'
]);
$stack->push($middleware);
$client = new Client([
'base_uri' => 'https://api.twitter.com/1.1/','handler' => $stack
]);
// Set the "auth" request option to "oauth" to sign using oauth
$res = $client->get('account/verify_credentials.json',['auth' => 'oauth']);
您可以按照guzzle/oauth-subscriber
的{{3}}(docs)来获取更多信息。
原因不是在CURL选项中,而是在无效的签名中,因为据我了解,它取决于时间戳。所以我不能使用带有不同时间戳的签名