connecting to flickr using PHP and PECL oAuth extension

flickr, one of the world dominant in photo sharing service, has added support to oAuth recently. Though their old authentication system still works (marked as deprecated but not discontinued) I find it’s wise to use their oAuth system for the better future proof application development.

PHP has a nice extension to perform oAuth dance in it’s pecl repository – pecl oAuth. Here is the code to connect to flickr using this extension. The only catch I found and took me more than 30 minutes to figure out a failed attempt, is you will have to append the permission flag in it’s oAuth authorization url. Pass either one of these permission flags “read”,”write” or “delete” as “&perms=” (flickr.php, line # 20) and then the redirection will be successful. Register your Flickr application from here, you will find your consumer key and secret key in next page in the App Garden.

While creating new application in flickr app garden, point the callback url to your flickr.php – thats it.

source code of config.php

<?php
$oauth['flickr']['consumerkey']="9e251c5bcc*********cac050bf50ef";
$oauth['flickr']['consumersecret']="d1c057904945****";
$oauth['flickr']['requesttokenurl']="http://www.flickr.com/services/oauth/request_token";
$oauth['flickr']['accesstokenurl']="http://www.flickr.com/services/oauth/access_token";
$oauth['flickr']['authurl']="http://www.flickr.com/services/oauth/authorize";
?>

And here is the source code of flickr.php

<?php
/**
 * flickr authentication script based on
 * pecl oauth extension
 */
session_start();
include_once("config.php");
/*
unset($_SESSION['frequest_token_secret']);
unset($_SESSION['faccess_oauth_token']);
unset($_SESSION['faccess_oauth_token_secret']);
 */
$oauthc = new OAuth($oauth['flickr']['consumerkey'],
        $oauth['flickr']['consumersecret'],
        OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_URI); //initiate
if(empty($_SESSION['frequest_token_secret'])) {
    //get the request token and store it
    $request_token_info = $oauthc->getRequestToken($oauth['flickr']['requesttokenurl']); //get request token
    $_SESSION['frequest_token_secret'] = $request_token_info['oauth_token_secret'];
    header("Location: {$oauth['flickr']['authurl']}?oauth_token=".$request_token_info['oauth_token']."&perms=read");//forward user to authorize url with appropriate permission flag
}
else if(empty($_SESSION['faccess_oauth_token'])) {
    //get the access token - dont forget to save it 
    $request_token_secret = $_SESSION['frequest_token_secret'];
    $oauthc->setToken($_REQUEST['oauth_token'],$request_token_secret);//user allowed the app, so u
    $access_token_info = $oauthc->getAccessToken($oauth['flickr']['accesstokenurl']);
    $_SESSION['faccess_oauth_token']= $access_token_info['oauth_token'];
    $_SESSION['faccess_oauth_token_secret']= $access_token_info['oauth_token_secret'];
}
if(isset($_SESSION['faccess_oauth_token'])) {
    //now fetch current users profile
    $access_token = $_SESSION['faccess_oauth_token'];
    $access_token_secret =$_SESSION['faccess_oauth_token_secret'];
    $oauthc->setToken($access_token,$access_token_secret);
    $data = $oauthc->fetch('http://api.flickr.com/services/rest/?method=flickr.test.login&api_key=ae29ce34e831937ac26483498e93f3e9&format=json');
    $response_info = $oauthc->getLastResponse();
    echo "<pre>";
    print_r(json_decode($response_info));
    echo "</pre>";
}
?>

You can download the complete package from here (Thanks Box.net)

Note: I have written a similar post to demonstrate connecting to twitter and linkedin via their oAuth protocol which you can find here :)

Complete oAuth script for Twitter and LinkedIn using PECL oAuth Extension

After searching for help to connect with LinkedIn via their oAuth protocol using PECL oAuth extension, I’ve found that lots of people are posting in their forum for the code samples. And only very few obscure code examples are available. I’ve found phplinkedin script but that is just too bulky for a simple oAuth dance :)

So here are two files to perform 3 step oAuth Dance for both twitter and linkedin. Just set your consumer key and consumer secret key in these scripts (config.php) and in your LinkedIn and Twitter application, set the url of these scripts as authentication callback :) thats it :)

check out the source code below or just straight download them from the following url
http://www.box.net/shared/oc0u7ym5y7

config.php: source

<?
//config.php
$oauth['twitter']['consumersecret']="UtNkcJC5VqmHgSgxMIRl2UcHaJLWINzr1g2q*****";
$oauth['twitter']['consumerkey']="LveyUCUf9Ym96AU7*****";
$oauth['twitter']['requesttokenurl']="http://twitter.com/oauth/request_token";
$oauth['twitter']['accesstokenurl']="http://twitter.com/oauth/access_token";
$oauth['twitter']['authurl']="http://twitter.com/oauth/authorize";
$oauth['linkedin']['consumersecret']="SX9FS_Ptz7yNA3WtTW0e8z3_XSiROnVSpOEbAVCfKAn7fqFq4kjelVXiNMO*****";
$oauth['linkedin']['consumerkey']="qQkxCNYQbuALhWyBZO03V--6dtwUnQHz7KFE4PBpdIL6hy_87SHygEZAJj9*****";
$oauth['linkedin']['requesttokenurl']="https://api.linkedin.com/uas/oauth/requestToken";
$oauth['linkedin']['accesstokenurl']="https://api.linkedin.com/uas/oauth/accessToken";
$oauth['linkedin']['authurl']="https://api.linkedin.com/uas/oauth/authorize";
?>

twitter.php: source

<?
//twitter.php
/**
 * twitter authentication script based on
 * pecl oauth extension
 */
session_start();
include_once("config.php");
/*
unset($_SESSION['trequest_token_secret']);
unset($_SESSION['taccess_oauth_token']);
unset($_SESSION['taccess_oauth_token_secret']);
 */
$oauthc = new OAuth($oauth['twitter']['consumerkey'],
        $oauth['twitter']['consumersecret'],
        OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_URI); //initiate
if(empty($_SESSION['trequest_token_secret'])) {
    //get the request token and store it
    $request_token_info = $oauthc->getRequestToken($oauth['twitter']['requesttokenurl']); //get request token
    $_SESSION['trequest_token_secret'] = $request_token_info['oauth_token_secret'];
    header("Location: {$oauth['twitter']['authurl']}?oauth_token=".$request_token_info['oauth_token']);//forward user to authorize url
}
else if(empty($_SESSION['taccess_oauth_token'])) {
    //get the access token - dont forget to save it 
    $request_token_secret = $_SESSION['trequest_token_secret'];
    $oauthc->setToken($_REQUEST['oauth_token'],$request_token_secret);//user allowed the app, so u
    $access_token_info = $oauthc->getAccessToken($oauth['twitter']['accesstokenurl']);
    $_SESSION['taccess_oauth_token']= $access_token_info['oauth_token'];
    $_SESSION['taccess_oauth_token_secret']= $access_token_info['oauth_token_secret'];
}
if(isset($_SESSION['taccess_oauth_token'])) {
    //now fetch current users profile
    $access_token = $_SESSION['taccess_oauth_token'];
    $access_token_secret =$_SESSION['taccess_oauth_token_secret'];
    $oauthc->setToken($access_token,$access_token_secret);
    $data = $oauthc->fetch('http://twitter.com/account/verify_credentials.json');
    $response_info = $oauthc->getLastResponse();
    echo "<pre>";
    print_r(json_decode($response_info));
    echo "</pre>";
}
?>

linkedin.php: source

<?
//linkedin.php
/**
 * linkedin authentication script based on
 * pecl oauth extension
 */
session_start();
include_once("config.php");
/*
unset($_SESSION['lrequest_token_secret']);
unset($_SESSION['laccess_oauth_token']);
unset($_SESSION['laccess_oauth_token_secret']);
 */
$oauthc = new OAuth($oauth['linkedin']['consumerkey'],
        $oauth['linkedin']['consumersecret'],
        OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_AUTHORIZATION); //initiate

$oauthc->setNonce(rand());

if(empty($_SESSION['lrequest_token_secret'])) {
    //get the request token and store it
    $request_token_info = $oauthc->getRequestToken($oauth['linkedin']['requesttokenurl']); //get request token
    $_SESSION['lrequest_token_secret'] = $request_token_info['oauth_token_secret'];
    header("Location: {$oauth['linkedin']['authurl']}?oauth_token=".$request_token_info['oauth_token']);//forward user to authorize url
}
else if(empty($_SESSION['laccess_oauth_token'])) {
    //get the access token  - dont forget to save it
    $request_token_secret = $_SESSION['lrequest_token_secret'];
    $oauthc->setToken($_REQUEST['oauth_token'],$request_token_secret);//user allowed the app, so u
    $access_token_info = $oauthc->getAccessToken($oauth['linkedin']['accesstokenurl']);
    $_SESSION['laccess_oauth_token']= $access_token_info['oauth_token'];
    $_SESSION['laccess_oauth_token_secret']= $access_token_info['oauth_token_secret'];
    $_SESSION['loauth_verifier'] = $_REQUEST['oauth_verifier'];
}
if(isset($_SESSION['laccess_oauth_token'])) {
    //now fetch current user's profile
    echo "<pre>";
    $access_token = $_SESSION['laccess_oauth_token'];
    $access_token_secret =$_SESSION['laccess_oauth_token_secret'];
    $oauth_verifier = $_SESSION['loauth_verifier'];
    $oauthc->setToken($access_token,$access_token_secret);
    $data = $oauthc->fetch('http://api.linkedin.com/v1/people/~');
    $response_info = $oauthc->getLastResponse();
    print_r(htmlspecialchars($response_info));
    echo "</pre>";
}
?>

Download these files from http://www.box.net/shared/oc0u7ym5y7 – Happy dancing time, in oAuth way ;)

using oauth pecl extension to talk to twitter

if you are interested in developing twitter applications, you must have read about twitter API and it’s authentication protocol. your application can fetch user’s private data but it has to authenticate itself as the user for that. so there are two ways to do it

1. asking user to provide his twitter username and password to your application (well, i am not interested to give away my PASSWORD to anyone!!!)
2. let twitter handle the authentication on behalf of you and ask user to grant permission to your application (hmm!! interesting)

now you see that #2 is more safe for your user. and i think most security concerned users will choose this way. so your application have to initiate this type of authentication system using twittter’s supported authentication protocol oAuth (it’s a commonly used authentication protocol used among number of popular service providers like yahoo, google and others)

to implement oauth in php, the best way is to use an existing library. there are now numbers of libraries available for this purpose. following are some of them
1. oauth lib by andy smith
2. oauth library by marc worrell
3. oauth pecl extension by rasmus lerdorf and john jawed and felipe pena

now you see, pecl extensions are written in c and runs pretty faster. so i choose it without thinking much abt it. i have assumed that you know how to install a pecl extension in your php hosting and i am not going to blog detail about that right now. all that can help you right now is shell command “pecl install -f oauth” – you know, nothing talks better than command or code :)

after installing oauth extension in my hosting account, i start developing my twitter application. first i have to register my application with twitter. you can create your one by pointing your browser to http://twitter.com/oauth_clients/new. please remember that you have to provide a callback url which twitter use to redirect user of your application after a success/unsuccessful authentication. i will refer to that url as “callback_url” through out this blog post. my applications callback_url is “http://mydomain.tld/auth.php&#8221;

after you have done registering your application with twitter, it will give you the following important data.
1. consumer key
2. consumer secret
3. request token url
4. access token url
5. authorize url

you will be going to use all of these in your application. now lets see how oauth works in brief. it initiate the talk using your consumer key and secret key. and then it request the “request token” from the service provider. if u r successful, you have to forward user of your application to the “authorize url” with the “request token”. now the service provider will ask to grant permission to your application from the user. if user grants (or disagree) the permission, the service provider (here, twitter) will forward your user again to the “callback url” of your application with a “new token”. now with the help of this new token and the token grabbed from previous “request token” your application will ask for “access token”. once you have the access token, you can authorize you application as the user itself with same privilege.

lets see how to do it in php with the help of oauth pecl extension. here we are going to initiate the talk, get the token and forward user to the service provider’s authorizing url.

token.php

< ?php
//token.php
$oauth = new OAuth("consumer key","consumer secret",OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_URI); //initiate
$request_token_info = $oauth->getRequestToken("http://twitter.com/oauth/request_token"); //get request token
file_put_contents("token.txt",$request_token_info['oauth_token_secret']);//store the oauth token secret of request token
header('Location: http://twitter.com/oauth/authorize?oauth_token='.$request_token_info['oauth_token']);//forward user to authorize url
?>

you see that we are storing the oauth_token_secret of the “request_token” because we need it in our next step to fetch access token. in the example above i am storing it in flat file, but you will have to store it in db/file with proper index to the userid so that you can retrieve it later in our next step.

if user visit this page, he will be redirected to twitter authorize url and that may look like the following one with different app name.
picture-26

now lets see how we handle if the user click “allow” or “deny” in the above page.

this is the callback file you specified in settings of your app [auth.php]

< ?php
//auth.php
$oauth = new OAuth("consumer key","consumer secret",OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_URI); //initiate
$request_token_secret = file_get_contents("token.txt"); //get the oauth_token_secret of request token we stored previously
if(!empty($_GET['oauth_token'])){
$oauth->setToken($_GET['oauth_token'],$request_token_secret);//user allowed the app, so u 
$access_token_info = $oauth->getAccessToken('http://twitter.com/oauth/access_token');
}
?>

access token is the most important token for your application. there are two object in this token – one is “oauth_token” and “oauth_token_secret”. if you print_r the access token it will look like the following one (actual value is not shown here)

Array ( 
    [oauth_token] => abcdefg 
    [oauth_token_secret] => uvwxyz
) 

you have to store this access token for authorizing later as this user (the user that was visiting). using this token you can anytime authorize yourself as that user and fetch user’s data from twitter. so lets see how we can fetch user’s profile data in rss (or json) format. the REST API url to fetch this data is “http://twitter.com/account/verify_credentials.json&#8221;. you can find other important REST urls to fetch user’s timeline, public timeline and friends timeline (also update status) in twitter’s documentation of it’s REST API

fetch user’s profile data

< ?php
//profile.php
$oauth = new OAuth("consumer key","consumer secret",OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_URI); //initiate
$oauth->setToken($accesstoken['oauth_token'],$accesstoken['oauth_token_secret']);
$data = $oauth->fetch('http://twitter.com/account/verify_credentials.json');
if($data){
    $response_info = $oauth->getLastResponse();
    echo "<pre>";
    print_r(json_decode($response_info));
    echo "</pre>";
}

the output of this code is the following one (my twitter username is hasin)

stdClass Object
(
    [time_zone] => Dhaka
    [friends_count] => 97
    [profile_text_color] => 666666
    [description] => Smoking too much PHP
    [following] => 
    [utc_offset] => 21600
    [favourites_count] => 2
    [profile_image_url] => http://s3.amazonaws.com/twitter_production/profile_images/84574185/afif_b_normal.jpg
    [profile_background_image_url] => http://s3.amazonaws.com/twitter_production/profile_background_images/5565492/777481225666153.jpg
    [profile_link_color] => 2FC2EF
    [screen_name] => hasin
    [profile_sidebar_fill_color] => 252429
    [url] => http://hasin.wordpress.com
    [name] => hasin
    [protected] => 
    [status] => stdClass Object
        (
            [text] => ok, understood how twitter auth works via oauth pecl ext. of #php. thanks to @rasmus for his excellent example
            [in_reply_to_user_id] => 
            [favorited] => 
            [in_reply_to_screen_name] => 
            [truncated] => 
            [created_at] => Sat May 02 16:08:28 +0000 2009
            [id] => 1679349376
            [in_reply_to_status_id] => 
            1 => web
        )

    [profile_sidebar_border_color] => 181A1E
    [profile_background_tile] => 1
    [notifications] => 
    [statuses_count] => 1147
    [created_at] => Fri Nov 09 10:40:14 +0000 2007
    [profile_background_color] => 1A1B1F
    [followers_count] => 265
    [location] => Dhaka, Bangladesh
    [id] => 10094392
)