Authenticating with OAuth from PHP

I've been looking into OAuth recently and really like what I see, so I started looking at actually starting to play with something that uses it (and isn't twitter). In the pursuit of this, I spent some time walking through the process of how to actually authenticate using OAuth, as a client. I chose Yahoo!'s service, because they have some fabulous developer documentation and have a standard OAuth implementation. Although you don't strictly need any special libraries to handle OAuth, that would be a bit like decoding XML with a regex, so I used the OAuth Package from PECL. For others (including me after I've slept), here's an outline of the process.


Consumer Key and Secret

This is comparable to an API key, like flickr uses, some credentials that you are going to use to say that you are you. You get these by signing up in advance.

Get a Request Token

This is falling-off-a-log simple with PECL::OAuth - I literally created a new object and told it to get a request item - this is a snippet from my main script, where $config is defined in a config file (hopefully it is explanatory enough that you can guess what would be in each element)

$oauth = new OAuth($config['consumer_key'],
                    $config['consumer_secret']
                    ); 
$oauth->setAuthType(OAUTH_AUTH_TYPE_URI);
$oauth->enableDebug();
 
// request token
$req = $oauth->getRequestToken($config['request_uri'], "oob");

Told you it was simple :) When I called this code, I got a response that looked something like this (this is not real data):

array(5) {
  ["oauth_token"]=>
  string(7) "hrsvppn"
  ["oauth_token_secret"]=>
  string(40) "f131a021ee3fb5bad48f0bc66e0129a3e820ab35"
  ["oauth_expires_in"]=>
  string(4) "3600"
  ["xoauth_request_auth_url"]=>
  string(69) "https://api.login.yahoo.com/oauth/v2/
request_auth?oauth_token=hrsvppn"
  ["oauth_callback_confirmed"]=>
  string(4) "true"         
}

At this point, you forward your user to that xoauth_request_auth_url and they will be prompted to log in.

User Logs In

So the user is on Yahoo!'s page, and they provide their Yahoo! credentials. As both a developer and as a user, I'm pleased that we don't have any typing of credentials into third party sites in this system. At this point, what happens next depends whether you are a web application or an app of some kind...

Take a look at the second argument to oauth::getRequestToken above, I've passed the value 'oob'. This is because I was writing a CLI PHP script on my local machine, so Yahoo! can't call back to my script. If this was a web application (or indeed anything that can be accessed by some kind of URL - smart phones have a thing to be able to launch particular apps from the browser), then we would pass our callback URL there and after authenticating, Yahoo! would forward our user to that URL with some data in the payload.

Since the user cannot be forwarded to me in this instance, Yahoo does not forward on the user; instead it shows the user a page containing their verification code. OAuth is designed with this in mind so the verification codes are short enough to retype (6 characters in this instance), and the user comes back to my application manually.

Get an Access Token

At this point, we know who the user is, we've sent them to the provider, the provider knows who they are, and they've sent them back, so you might be excused for thinking we had finished authenticating! However there is one final step, to request the access token. We send the request token and the verification code to the provider, and they send us an access token in response.

My code for this looked something like:

// create oauth object 
$oauth = new OAuth($config['consumer_key'],
                    $config['consumer_secret']   
                    );
 
$oauth->setAuthType(OAUTH_AUTH_TYPE_URI);
 
$oauth->setToken($config['request_token'], $config['request_token_secret']);
$access = $oauth->getAccessToken($config['access_uri'], null, $config['verification']);

Again, we create an OAuth object in the same way, and we use our request token details, consumer key and secret, and the verification code to request the access token that we need to work with the rest of the service. The response looked like this (data is scrambled but in a fairly similar format):

array(6) {                                                 
  ["oauth_token"]=> 
  string(742) "A=On6YEu7g5TN ... 8QOXhY-" 
  ["oauth_token_secret"]=>
  string(40) "be90c895bfbf7d49e3b557fb446c0a76e21070f7"
  ["oauth_expires_in"]=>
  string(4) "3600"           
  ["oauth_session_handle"]=>
  string(48) "ADsnZ_MLimUxhz1PF7lm.Y1BhmkF0ivGcIn69zRwurCvetRJ"
  ["oauth_authorization_expires_in"]=>
  string(9) "862329612" 
  ["xoauth_yahoo_guid"]=> 
  string(26) "TBZETP42IUQE3N4GEXB55VDMAA" 
}

Authenticated!

Now you are authenticated and can start making calls against the various Yahoo! services. The process should be very similar for most OAuth implementations, and although it might seem like a faff, in fact it is a secure and elegant authentication method, and with twitter adopting it, hopefully many more providers will too!

11 thoughts on “Authenticating with OAuth from PHP

  1. I'm working with Google Analytics at the moment, to pull information about web traffic from analytics into another system. Google have excellent APIs and that makes this job much easier. I'm using pecl_oauth to authenticate users against their google ac

  2. I've been working with OAuth, as a provider and consumer, and there isn't a lot of documentation around it for PHP at the moment so I thought I'd share my experience in this series of articles. This relates to the stable OAuth 1.0a spec, however OAuth2 h

  3. I am trying to use the OAuth authentication for JIRA which is a bug tracking tool.

    Can you help me with some knowledge about the PHP implementation for it

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>