OAuth PHP Tutorial

Here's a brief demo on how to authenticate against Justin.tv's OAuth using PHP. You'll need the PHP OAuth library (oauth.php), available here [[1]].

First, look at my config.php, which uses cURL and URLs returned by the OAuth library. This is standard cURL, and involves no OAuth-specific code.


<?
function doHttpRequest($urlreq)
{
$ch = curl_init();

// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "$urlreq");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);

// grab URL and pass it to the browser
$request_result = curl_exec($ch);

// close cURL resource, and free up system resources
curl_close($ch);

return $request_result;
} ?>

Now, on index.php, we see how we can make our first oAuth requests.


<?
require_once ("OAuth.php");
require_once ("config.php");

$key = '';//'<your app's API key>';
$secret = '';//'<your app's secret>';

$base_url = "<URL where your app is hosted>";
$request_token_endpoint = 'http://api.justin.tv/oauth/request_token';
$authorize_endpoint = 'http://api.justin.tv/oauth/authorize';

$test_consumer = new OAuthConsumer($key, $secret, NULL);

//prepare to get request token

$sig_method = new OAuthSignatureMethod_HMAC_SHA1();
$parsed = parse_url($request_token_endpoint);
$params = array(callback => $base_url);
parse_str($parsed['query'], $params);

$req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $request_token_endpoint, $params);
$req_req->sign_request($sig_method, $test_consumer, NULL);

$req_token = doHttpRequest ($req_req->to_url());

//assuming the req token fetch was a success, we should have
//oauth_token and oauth_token_secret

parse_str ($req_token,$tokens);

$oauth_token = $tokens['oauth_token'];
$oauth_token_secret = $tokens['oauth_token_secret'];

$callback_url = "$base_url/callback.php?key=$key&token=$oauth_token&token_secret=$oauth_token_secret&endpoint="
                    . urlencode($authorize_endpoint);

$auth_url = $authorize_endpoint . "?oauth_token=$oauth_token&oauth_callback=".urlencode($callback_url);

//Forward us to justin.tv for auth
Header("Location: $auth_url");

?>

This is fairly self explanatory. It's important to realize that the reason for this request is for your app's server to contact the justin.tv server yourself, and obtain a token. You then forward the user to justin.tv's authentication page with that token. J.tv will redirect your users back to the $callback_url. In this case, it's $base_url/callback.php, but you can change it to be any page on your site.

Now, on callback.php, we can make our first signed request to oAuth.


<?
require_once ("OAuth.php");
require_once ('config.php');

$key = ''; //Replace with your app's API key
$secret = ''; //Replace with your app's secret key
$oauth_access_token_endpoint = 'http://api.justin.tv/oauth/access_token';
$oauth_authorize_endpoint = "http://api.justin.tv/oauth/authorize";

$base_url = "<URL of your app>"; //Replace with your app's URL

//We were passed these through the callback.
$token = $_REQUEST['token'];
$token_secret = $_REQUEST['token_secret'];

$consumer = new OAuthConsumer($key, $secret, NULL);
$auth_token = new OAuthConsumer($token, $token_secret);
$access_token_req = new OAuthRequest("GET", $oauth_access_token_endpoint);
$access_token_req = $access_token_req->from_consumer_and_token($test_consumer,
                $auth_token, "GET", $oauth_access_token_endpoint);

$access_token_req->sign_request(new OAuthSignatureMethod_HMAC_SHA1(),$consumer,
                $auth_token);

$after_access_request = doHttpRequest($access_token_req->to_url());
parse_str($after_access_request,$access_tokens);

$access_token = new OAuthConsumer($access_tokens['oauth_token'], $access_tokens['oauth_token_secret']);

$streamkey_req = $access_token_req->from_consumer_and_token($consumer,
                $access_token, "GET", "http://api.justin.tv/api/channel/stream_key.xml");

$streamkey_req->sign_request(new OAuthSignatureMethod_HMAC_SHA1(),$consumer,$access_token);

$after_request = doHttpRequest($streamkey_req->to_url());

//Get streamkey from returned XML
$stream_key = parseStream_KeyFromXML ($after_request);

if ($stream_key == '')
    echo ("Error getting stream_key from API!");
else
{   //We got the key! Embed the broadcaster and we're done.
    ?>
    <html>
    <OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
     codebase=""http://macromedia.com/cabs/swflash.cab#version=6,0,0,0""
     WIDTH="250" HEIGHT="250" id="flaMovie1" ALIGN="CENTER">
     <PARAM NAME=movie VALUE="http://www.justin.tv/widgets/live_embed_publisher.swf">
     <PARAM NAME=FlashVars VALUE="stream_key=<? echo $stream_key; ?>">
     <PARAM NAME=quality VALUE=high>
     <PARAM NAME=bgcolor VALUE=#FFFFFF>
     <embed src="http://www.justin.tv/widgets/live_embed_publisher.swf" FlashVars="stream_key=<? echo $stream_key; ?>"
      quality="high" bgcolor="#FFFFFF" WIDTH="250" HEIGHT="250"
      NAME="flaMovie1" ALIGN TYPE="application/x-shockwave-flash"
      PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer">
    </OBJECT>
    </html>
    <?
}

//helper function to get the stream_key from returned XML
function parseStream_KeyFromXML($xml)
{
    $xml_parser = xml_parser_create();

    xml_parse_into_struct($xml_parser, $xml, $vals, $index);
    xml_parser_free($xml_parser);

    if ($vals[1]['tag'] == "STREAM_KEY")
        return $vals[1]['value'];
    else
        return '';
}?>

This callback page uses the tokens forwarded from the authenticated user, and then contacts justin.tv again, this time with the request token. This provides us with an access token, which we then use to call the function channel/stream_key. All of the calls are documented in the REST API Documentation.

We then use the newly obtained stream_key to load the justin.tv embed broadcaster, allowing a user to broadcast on their channel from your page through Flash.