Understanding OAuth – Tweeting from Scratch, Part 2

This entry is part 2 of 2 in the series Understanding OAuth - Tweeting from Scratch

Understanding OAuth - Tweeting from Scratch

Welcome back to Understanding OAuth – Tweeting from Scratch. This is Part 2 of the two-part series and picks up right where we left off in Part 1 with your returned Access Credentials. Since obtaining the credentials is the grueling part of the process, there’s not much more left to do except posting a tweet on the user’s behalf. Hopefully you’ll find the final steps to be a lot easier to follow and more fun to implement.

First things first, you should at least store the user specific details and credentials from Part 1 in $_SESSION so they can be used later, though most likely you’ll want to store the information in a database so you can retrieve them whenever you like to send tweets on behalf of others.

<?php
//...
$response = file_get_contents($requestUrl);
parse_str($response, $values);

$_SESSION["accessToken"] = $values["oauth_token"];
$_SESSION["accessTokenSecret"] = $values["oauth_token_secret"];
$_SESSION["twitterUserId"] = $values["user_id"];
$_SESSION["twitterUsername"] = $values["screen_name"];

// Redirect the user to the application's form 
header("Location: /postTweet.php");

Since your application has the necessary Access Credentials and you’ve tucked them away safely for future use, you can redirect the user to a form where he can enter the text of his tweet.

<form action="/postTweet.php" method="post">
 <textarea name="tweet" rows="3" cols="50"></textarea>
 <br>
 <input type="submit" value="Send">
</form>

Posting to Twitter

There is plenty you can do with the Twitter API once you have Access Credentials (full API documentation can be found at dev.twitter.com/docs/api). For this article I’m showing just the use of statuses/update to to post a tweet. You can request many of the API calls to respond with XML or JSON formatted data simply by adding .xml or .json to the end of the URL. Personally I find JSON far easier to deal with than XML.

statuses/update requires an HTTP POST to be made sending your OAuth parameters in the HTTP header. Previously you only used GET in the conversations with Twitter.

All OAuth v1 Twitter API resource URLs begin with “http://api.twitter.com/1/” and end with the resource name followed by .xml or .json. The only credentials you need from now on are your Consumer Credentials and the Access Credentials; the Request Credentials are discarded since they were only necessary for the authorization process.

Building the signature is performed the same as before except you now include the Access Token Secret in $sigKey.

<?php
$oauthVersion = "1.0";
$apiResourceUrl = "http://api.twitter.com/1/statuses/update.json"; 
$nonce = md5(mt_rand()); 
$oauthSignatureMethod = "HMAC-SHA1"; 
$oauthTimestamp = time();
$accessToken = $_SESSION["accessToken"];
$accessTokenSecret = $_SESSION["accessTokenSecret"];
$tweetText = trim($_POST["tweet"]);

$sigBase = "POST&" . rawurlencode($apiResourceUrl) . "&"
    . rawurlencode("oauth_consumer_key=" . rawurlencode($consumerKey)
    . "&oauth_nonce=" . rawurlencode($nonce)
    . "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
    . "&oauth_timestamp=" . $oauthTimestamp
    . "&oauth_token=" . rawurlencode($accessToken)
    . "&oauth_version=" . rawurlencode($oauthVersion)
    . "&status=" . rawurlencode($tweetText));
$sigKey = rawurlencode($consumerSecret) . "&" . rawurlencode($accessTokenSecret); 
$oauthSig = base64_encode(hash_hmac("sha1", $sigBase, $sigKey, true)); 

OAuth POST transactions can (and are required to by Twitter) have the OAuth parameters included in a special Authorization HTTP header. It’s worth noting that besides the typical OAuth parameters, $sigBase also includes the API resource parameter status above. Non-OAuth parameters are needed in the signature but are excluded from the HTTP header. They are used in the POST body instead.

<?php
$authHeader = "OAuth oauth_consumer_key=" . rawurlencode($consumerKey) . ","
    . "oauth_nonce=" . rawurlencode($nonce) . ","
    . "oauth_signature_method=" . rawurlencode($oauthSignatureMethod) . ","
    . "oauth_signature=" . rawurlencode($oauthSig) . ","
    . "oauth_timestamp=". rawurlencode($oauthTimestamp) . ","
    . "oauth_token=" . rawurlencode($accessToken) . ","
    . "oauth_version=" . rawurlencode($oauthVersion); 

$httpPostDataUrl = "status=" . $tweetText; 

$context = stream_context_create(array("http" => array(
    "method" => "POST", 
    "header" => "Content-Type: application/x-www-form-urlencodedrnAuthorization: " . $authHeader . "rn", 
    "content" => $httpPostDataUrl)));

$result = file_get_contents($apiResourceUrl, false, $context);

If everything went smoothly you should have just posted to twitter on behalf of an authorized user. Twitter sends the success or failure status along with a very large amount of information regarding the transaction, which you can with print_r(json_decode($result)) if you like.

Summary

Now that you have a fair understanding of how Oauth works, implementing a third party library or troubleshooting OAuth in general should be a lot easier. In summary, you’ve learned how to:

  • Create a new Twitter application and obtain the Consumer Credentials
  • Obtain the Request Credentials which are necessary for requesting Access Credentials
  • Authorize your application with a user and obtain Access Credentials
  • Post a tweet on another user’s behalf using the Access Credentials

Today some of the most popular web applications provide access to an API – Flickr, Facebook, foursquare, Netflix, Last.fm, and GetGlue to name a few. Having an intimate knowledge of how to seamlessly communicate with these applications is a very desirable skill! Some of what you have learned here regarding the hashing of signatures and exchange of tokens can also be well applied to non-Oauth v1.0 APIs, such as Flickr’s pre-OAuth interface and the much easier to understand OAuth v2. Good luck and have fun!

Code for this series can be found on GitHub.

Image via Photosani / Shutterstock

Understanding OAuth - Tweeting from Scratch

<< Understanding OAuth – Tweeting from Scratch, Part 1

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • http://blazejklisz.pl Błażej Klisz

    Once again thanks for nice tutorial.

  • http://twitter.com/lddurbin Lee

    Great tutorial, but it appears to be broken here. I’ve successfully worked my way through the first part, but when I follow the method on this page I receive the following response:

    stdClass Object ( [error] => Could not authenticate you. [request] => /1/statuses/update.json )

    I’ve tried building the app myself, and I’ve also downloaded the original source files you kindly supplied, and tried sending a test tweet after authenticating successfully – no dice. Any ideas here?

    • http://codepixelz.com Utsav

      Did you get something for it yet? I am having the same problem.

  • Chris

    I have the same problem, unfortunately.

    For some reason it appears related to the $tweetText

    I can send my tweet successfully using this guide, but only if:
    $httpPostDataUrl = “status=” . rawurlencode($tweetText);

    Problem is the Tweet is then urlencoded and illegible.