Search code examples
phpoauthtwitter-oauthguzzlephp-curl

How to reproduce OAuth1.0 Request Headers in PHP CURL


I am trying to make Twitter verify_credentials request on webserver using PHP 7.4.

I get a http 200 code and proper response only when I set OAuth1.0 Request Headers settings in Postman like that:

How I made request in Postman and it works

Any other way to make request with the same data returns me an error with 401 http status code

{"errors":[{"code":32,"message":"Could not authenticate you."}

I need to convert this Postman settings in PHP CURL of GUZZLE or another http request client code. But when I import CURL examples from Postman, it always throws the same 401 exception. So I tried different ways:

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

Or another one:

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

Or that way:

// 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_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=\"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);

Every time get an 401 error. So, how can I set up all OAuth1.0 properties in PHP CURL to reproduce the same request with the same headers which works in Postman?

P.S. I have already tried abraham/twitteroauth, laravel/socialite and other solutions with the same result


Solution

  • The cause was not in CURL options but in invalid signature, because it depends on timestamp as I understand it. So I cannot use one signature with different timestamps