I am trying to generate a signature for my Twitter or X API using just PHP and cURL. I don't want to use any library or package. I want to do it raw.
So far I have read the API docs and followed every step carefully but I am getting an error.
Here is the error I am getting ...
{"errors":[{"code":32,"message":"Could not authenticate you."}]}
And here is my code ...
<?php
date_default_timezone_set('UTC');
$keys = array(
"consumer_key" => "",
"consumer_secret" => "",
"bearer_token" => "",
"token_identifier" => "",
"token_secret" => ""
);
$method = "POST";
$status = "Hello World!";
$endpoint = ".1/statuses/update.json";
$nounce = bin2hex(random_bytes(16));
$params = [
"status" => $status,
"include_entities" => "true",
"oauth_consumer_key" => $keys['consumer_key'],
"oauth_nonce" => $nounce,
"oauth_signature_method" => "HMAC-SHA1",
"oauth_timestamp" => $T,
"oauth_token" => $keys['token_identifier'],
"oauth_version" => "1.0",
];
$signature = $API->signature($method, $endpoint, $params, $keys['consumer_secret'], $keys['token_secret']);
echo $signature . '<br><br>';
$authHeader = 'OAuth ';
$authParams = array(
"oauth_consumer_key" => $keys['consumer_key'],
"oauth_nonce" => $nounce,
"oauth_signature" => $signature,
"oauth_signature_method" => "HMAC-SHA1",
"oauth_timestamp" => $T,
"oauth_token" => $keys['token_identifier'],
"oauth_version" => "1.0",
);
$headerParts = [];
foreach ($authParams as $key => $value) {
if (strpos($key, 'oauth_') === 0) {
$headerParts[] = $key . '="' . rawurlencode($value) . '"';
}
}
$authHeader .= implode(', ', $headerParts);
echo $authHeader . '<br><br>';
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query(['status' => $status]),
CURLOPT_HTTPHEADER => [
'Authorization: ' . $authHeader,
'Content-Type: application/x-www-form-urlencoded',
],
]);
$response = curl_exec($curl);
echo curl_errno($curl) ? 'Curl error: ' . curl_error($curl) : 'Response: ' . $response . '<br><br>';
curl_close($curl);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
$response = curl_exec($curl);
echo curl_getinfo($curl, CURLINFO_HEADER_OUT);
?>
I tried using x endpoint and twitter endpoint and both returned the same error.
I have followed the instruction for the signature generation to the T but no luck so far.
Here is my signature function ...
function signature($method, $endpoint, $params, $consumerSecret, $tokenSecret = ''){
$encodedParams = [];
foreach($params as $key => $value){
$encodedParams[$key] = $value;
}
ksort($encodedParams);
$paramString = http_build_query($encodedParams, '', '&', PHP_QUERY_RFC3986);
// echo $paramString;
$encodedUrl = rawurlencode($endpoint);
$encodedParamString = rawurlencode($paramString);
$signatureBaseString = strtoupper($method) . "&" . $encodedUrl . "&" . $encodedParamString;
// echo $signatureBaseString;
$encodedConsumerSecret = rawurlencode($consumerSecret);
$encodedTokenSecret = rawurlencode($tokenSecret);
$signingKey = $encodedConsumerSecret . "&" . $encodedTokenSecret;
$hash = hash_hmac('sha1', $signatureBaseString, $signingKey, true);
$signature = base64_encode($hash);
return $signature;
}
Please do not ask why I am not using a library. I don't want to, I want to learn how to do it with only core PHP.
Any ideas why it's returning this error?
I am sure that I am using the right keys for the API generated by twitter.