Authorizing with oAuth, posting to Twitter Authorizing with oAuth, posting to Twitter curl curl

Authorizing with oAuth, posting to Twitter


I had three problems:

(1) I did not include it in this question, but my signature wasn't created correctly.

What I was doing was base64_encode(hash_hmac('sha1', $base, $key)); but I should have set the hash_hmac fourth parameter to true to return a raw binary instead of the hexidecimal (the hexidecimal is shown as the example in the Twitter docs, which was what was confusing me). The correct function is therefore: base64_encode(hash_hmac('sha1', $base, $key, true));.

(2) The cURL was not set up correctly. I required CURLOPT_HTTPHEADER to set the Authorization, and CURL_VERBOSE set to true:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $DST));curl_setopt($ch, CURLOPT_VERBOSE, 1);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.rawurlencode($status));curl_setopt($ch, CURLOPT_URL, $url);

(3) As seen in the above code, I had to post the status as a string, and not an array. I found the solution to this problem on this question: Why can't I authenticate with OAuth?.

All of this is now working perfectly. Also, make sure that your access token in your Twitter application says that the access level is "Read and write". If not, change the permissions in Settings, then go back to Details and recreate your access token.

Full Script

<?phpclass Tweet {public $url = 'https://api.twitter.com/1/statuses/update.json';function the_nonce(){    $nonce = base64_encode(uniqid());    $nonce = preg_replace('~[\W]~','',$nonce);    return $nonce;}function get_DST($status){    $url = $this->url;    $consumer_key = $your_consumer_key_here;    $nonce = $this->the_nonce();    $sig_method = 'HMAC-SHA1';    $timestamp = time();    $version = "1.0";    $token = $your_token_here;    $access_secret = $your_access_secret_here;    $consumer_secret = $your_consumer_secret_here;    $param_string = 'oauth_consumer_key='.$consumer_key.            '&oauth_nonce='.$nonce.            '&oauth_signature_method='.$sig_method.            '&oauth_timestamp='.$timestamp.            '&oauth_token='.$token.            '&oauth_version='.$version.            '&status='.rawurlencode($status);    $sig_base_string = 'POST&'.rawurlencode($url).'&'.rawurlencode($param_string);    $sig_key = rawurlencode($consumer_secret).'&'.rawurlencode($access_secret);    $tweet_sig = base64_encode(hash_hmac('sha1', $sig_base_string, $sig_key, true));    $DST = 'OAuth oauth_consumer_key="'.rawurlencode($consumer_key).'",'.        'oauth_nonce="'.rawurlencode($nonce).'",'.        'oauth_signature="'.rawurlencode($tweet_sig).'",'.        'oauth_signature_method="HMAC-SHA1",'.        'oauth_timestamp="'.rawurlencode($timestamp).'",'.        'oauth_token="'.rawurlencode($token).'",'.        'oauth_version="1.0"';    return $DST;}function set($status){    $url = $this->url;    $ch = curl_init();curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $this->get_DST($status)));curl_setopt($ch, CURLOPT_VERBOSE, 1);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.rawurlencode($status));curl_setopt($ch, CURLOPT_URL, $url);    $result = json_decode(curl_exec($ch));if(!curl_errno($ch)){    $info = curl_getinfo($ch);    if($info['http_code']!='200'){//error postingecho 'Error: '.$result->{'error'};    }else{//successecho 'Success! <a href="https://twitter.com/AOKHalifax/status/'.$result->{'id_str'}.'" target="_blank">View Tweet</a>';    }}else{    //error connecting    echo 'error posting';    }    curl_close($ch);    }}/* Usage example:$status = new Tweet();$status->set('checking'); */?>


Hi and thank you for your help.

I had the same problem, you'll find below my code:

<?phppublic function updateStatus($message){    // Encoding message for the curl data parameter    $messageData = rawurlencode($message);    // Double encoding message for the message in signature base string    $messageSignature = rawurlencode($messageData);    // URL for posting a new tweet    $statusURL = rawurlencode('https://api.twitter.com/'.$this->version.'/statuses/update.json');    // Create oauth_nonce parameter    $oauth_nonce = preg_replace('~[\W]~','',base64_encode(uniqid()));    // Create timestamp    $oauth_timestamp = time();    // Create signature base string parameter    $signature_base_string = "POST&".$statusURL."&oauth_consumer_key%3D".CB_TWITTER_API_KEY."%26oauth_nonce%3D".$oauth_nonce."%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D".$oauth_timestamp."%26oauth_token%3D".$this->sessionData['oauth_token']."%26oauth_version%3D1.0%26status%3D".$messageSignature."";    // Create signature key     $signature_key = CB_TWITTER_SECRET_KEY.'&'.$this->sessionData['oauth_token_secret'];    // Create new signature    $newSignature = rawurlencode(base64_encode(hash_hmac('sha1', $signature_base_string, $signature_key, true)));    // Create header    $header="Authorization:                 OAuth                 oauth_consumer_key=\"".CB_TWITTER_API_KEY."\",                 oauth_nonce=\"".$oauth_nonce."\",                 oauth_signature=\"".$newSignature."\",                 oauth_signature_method=\"HMAC-SHA1\",                 oauth_timestamp=\"".$oauth_timestamp."\",                 oauth_token=\"".$this->sessionData['oauth_token']."\",                 oauth_version=\"1.0\"";    // Replace line breaks and tabulations in header    $header = preg_replace( "/\r|\n|\t/", "", $header);    // Init cURL    $ch = curl_init();    // Put header    curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));    // Set request type to POST for POSTing a tweet    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');    // Enable verbose for debugging only    curl_setopt($ch, CURLOPT_VERBOSE, false);    // Return the transfer in a string    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    // Set URL of cURL request    curl_setopt($ch, CURLOPT_URL, rawurldecode($statusURL));    // Do a POST request (HTML POST)    curl_setopt($ch, CURLOPT_POST, 1);    // Set data    curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.$messageData);    // Execute cURL and store result    $output = curl_exec($ch);    // Close cURL    curl_close($ch);    if ($output) {        $output = json_decode($output);    }    if ($this->hasErrors($output, false))    {        return false;    }   return true;}?>

Hope it'll help.