Integrate Social Sign On in your PHP apps using HybridAuth

nt.social.network.big_

Integrating social sign-ons in a web application can become a tedious task because you need to take care of different endpoints, credentials and finally manage the oauth dance to get the access token. However, using HybridAuth package, this task can be easy as pie :) Let’s have a look

In this example I will show you how to connect to Facebook and Twitter using HybridAuth. So you need to create two applications in Facebook and Twitter each. Save those app’s id and secret somewhere because we will need that in a minute.

Step 1: Install the Package via Composer

Composer is an excellent package manager for PHP apps. Let’s use that to install HybridAuth in our current projects scope. Add a composer.json file in your project path, or update it with the following contents if it already exists. But before that, make sure that you have composer installed in this machine.

{
    "require": {
        "hybridauth/hybridauth": "3.0.0.*@dev"
    }
}

now run the following command to install hybridauth

composer install

Step 2: Connect with Facebook

Let’s make a good use of this HybridAuth. This time we need to create two files, fb.php and hybrid.php. Make sure that your facebook app’s callback url points to this hybrid.php. FOllowing is the code of fb.php Continue reading

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 ;)

collecting data from streaming APIs in twitter

twitter’s streaming API is still in beta and is a good source of collecting public tweets. but unfortunately not all those methods are instantly usable by third parties (u need to provide written statements and so on). but for testing, three of these streaming APIs are usable by anyone at this moment which are spritzer, track and follow. spritzer streams a tiny part of public tweets to the collecting processes. in this blog post i’ll show you how to collect data from spritzer API.

as it is a stream data, so twitter keeps the HTTP connection “alive” infinitely (until any hiccup, by using Keep Alive). so when you write code, you must take care of that. and i would also suggest to make separate processes for collecting data+writing them (or sending them in queue to be written) – and for analyzing those data. and of course, to minimize the bandwidth consumption, use the json format. and json data is also easier to parse than XML as every tweet is separated by a new line (“\n”) character from twitter :) – so you can read these data line by line, dcode them using json_decode() and do whatever you want

here is how you can create the collector process in php

< ?php
//datacollector.php
$fp = fopen("http://username:password@stream.twitter.com/spritzer.json","r");
while($data = fgets($fp))
{
    $time = date("YmdH");
    if ($newTime!=$time)
    {
        @fclose($fp2);
        $fp2 = fopen("{$time}.txt","a");
    }
    fputs($fp2,$data);
    $newTime = $time;
}
?>

this script will write the data collected hourly from the spritzer streaming API in filen (with names like <YmdH>.txt ). so in the directory where you are runnign this script u will see hourly data files. like 2009062020.txt . there is a special advantage to keep collecting in this way – as the file will remain open for writing (hence LOCKED) you will process files only for previous hours. it will make analyzing the data more hassle free :)

now run this script in background via the following command in your terminal

php datacollector.php &

the reason for appending an “&’ at the end of the command is starting this process in background. so that you dont have to wait for the script to end to get access to your shell back. as it is a streaming data, the script will run infinitely. and it will consume very minimal bandwidth :) you can check yourself.

so i hope it will help those developers who are looking for a solution to collect data from twitter’s streaming API via PHP. If you want to track any specific keywords, use the “track” API instead :). and if you want to follow some particular person use the “follow“. Check out twitter’s documentation of streaming API for more :)

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
)

Bug in twitter prevents you from updating your status

I’ve found it last night while trying to update my status in twitter. these days I am too much twittering and I was redirected to an url while exploring twitter. while trying to update my status, it failed repeatedly and then i’ve found that bug – lol

the url that reproduces the bug is http://explore.twitter.com/home – which looks similar to your actual twitter home (http://twitter.com/home) and it also shows you a twit box to update your status. but you cannot update your status from http://explore.twitter.com/home

check what was returned after the ajax request (u have firebug, right? do it yourself)

403 Forbidden: The server understood the request, but is refusing to fulfill it. If you are posting from an API tool please ensure that the HTTP_REFERER header is not set.

try before they fix it :) interesting usability bug indeed.