OAuth 2.0 PHP Library

Throughout the Linkey project I’ve been working on a number of PHP libraries that aim to make working with OAuth 2.0 easier.

The library is now at version 2.1, implements the entire core OAuth 2.0 specification and bearer token specification and has had over 1800 installations at the time of writing.

I’m very happy to announce that the University of Lincoln has agreed to transfer ownership of the code to the “PHP League of Extraordinary Packages” which means that it’ll continue to receive updates and be maintained by a number of developers around the world (myself included).

The server repository is now hosted at https://github.com/php-loep/oauth2-server and the client library is now hosted at https://github.com/php-loep/oauth2-client.

I have updated the wikis on both repositories with thorough documentation about how to use each library, and on the server library wiki I’ve added a lot more implementation about how to implement the library for common use cases.

My intention with all the code that has been written as an output of this project was that it would be as easy to use as possible and I’ve had some great feedback from developers:

— “Thanks for making your OAuth 2.0 server library public! It is people like you that make my job slightly more tolerable :)”

— “I wanted to thank you for your awesome library @alexbilbie :)”

— “Thank you for the great posts and lib”

— “If you drink, I will buy you a virtual beer!! What you built is awesome”

And finally in reply to a question that a developer asked me about how to do something with the library:

— “I’m really not surprised it was that simple – you’ve really built this with the end developer in mind. Once again, thanks very much for the info and the repo.”

To conclude I’m really happy with the code, I’ve learnt an awful lot as it has been developed and refined and I’m pleased that it’s new home will ensure long term sustainability.

Easily integrate other OAuth 2.0 identity providers with PHP

One of the other PHP libraries I’ve been working for Linkey is a PHP library that makes working with other OAuth 2.0 identity providers “stupidly easy”. I think I’ve done that and it’s time to announce the initial release – https://github.com/lncd/OAuth2-client.

So lets say you want to allow users to sign-in to their Facebook account:

$provider = new \OAuth2\Client\Provider\Facebook(array(
    'clientId'  =>  'XXXXXXXX',
    'clientSecret'  =>  'XXXXXXXX',
    'redirectUri'   =>  'http://your-registered-redirect-uri/'
));

if ( ! isset($_GET['code'])) {

    // If we don't have an authorization code then get one
    $provider->authorize();

} else {

    try {

        // Try to get an access token (using the authorization code grant)
        $t = $provider->getAccessToken('authorization_code', array('code' => $_GET['code']));

        try {

            // We got an access token, let's now get the user's details
            $userDetails = $provider->getUserDetails($t);

            foreach ($userDetails as $attribute => $value) {
                var_dump($attribute, $value) . PHP_EOL . PHP_EOL;
            }

        } catch (Exception $e) {

            // Failed to get user details

        }

    } catch (Exception $e) {

        // Failed to get access token

    }
}

Simple right? If you take out the try/catch statements then it essentially boils down to this:

$provider = new \OAuth2\Client\Provider\<provider name>(array(
    'clientId'  =>  'XXXXXXXX',
    'clientSecret'  =>  'XXXXXXXX',
    'redirectUri'   =>  'http://your-registered-redirect-uri/'
));

if ( ! isset($_GET['code'])) {

    $provider->authorize();

} else {

    $token = $provider->getAccessToken('authorization_code', array('code' => $_GET['code']));
    $userDetails = $provider->getUserDetails($token);
}

The library automatically manages the state parameter to help mitigate cross-site request forgery attacks (where supported by the end-IdP).

At the time of writing there is built in support for Facebook, Google and Github but adding support for other identity providers is trivial – you just need to extend the IdentityProvider class.

I will add support for more providers soon. There also aren’t any unit tests currently but they are coming.

The library is hooked up to Packagist so just add "lncd/oauth2-client": “*” to your composer.json file.

API driven development: eating your own dog food

On Tuesday I presented at the first ever PHP North East conference in Newcastle. Hosted in the fantastic Tyneside Cinema (which is the last surviving Newsreel theatre still operating as a cinema full-time in the UK), it was a very well organised event and I’m incredibly grateful to the PHP North East group for accepting my talk proposal.

My topic was “API driven development: Eating your own dog food”, I’ve embedded my slides below:

Unfortunately they weren’t able to video my talk so my slides may seem a little out of context but hopefully you can get the overall gist of what I talked about.

Once again, I’d like to say thank you to Anthony Sterling and the PHPNE crew for putting on a wonderful event.

Twitter’s official clients have their OAuth keys leak

Someone has posted a Github Gist with all of the client identifiers and secret keys for the official Twitter clients on various platforms.

This just highlights why it is imperitive that you don’t screw up like Facebook did by allowing wildcard client redirect URIs.

The client redirect URIs must be absolute and stored on the authorisation server.

So what can Twitter do about this?

They could release new binarys for all of their clients with new keys and invalidate the old keys, but clients that haven’t been updated will suddenly stop working and leave users confused and frustrated. Also it will be trivial for the new keys to be leaked too.

Alternatively they could come up with some sort of mechanism to allow the official clients to download new keys on the fly but then these could be captured with a man-in-the-middle attack.

But is it actually a problem?

First, it is important to recognise that this is really only a problem for desktop/mobile app clients (assuming that is that web server based clients themselves keep their keys secure – the differnece being that someone would have to break into a web server to get to them).

Therefore as long as Twitter aren’t giving their own applications additional functionality that 3rd party clients can’t replicate then there isn’t too much of a problem because with this equal playing field scenario it could be Tweetbot or MetroTwit we’re talking about.

Having said that, the official iOS mobile client at least does allow you to register a new account, so these leaked keys could be used to create spam accounts.

With 3rd party Twitter clients being limited to 100,000 access tokens this could tempt some to make use of these keys however if they were caught then they risk being named and shamed by the media and that in turn could also result in developer accounts being banned by Apple and Google from their app stores.

Is OAuth to blame?

No, the OAuth protocol is behaving as it designed to here. That is, if a 3rd party client presented a correctly formed request with these valid keys and the correct redirect URI then, assuming Twitter doesn’t have some extra security in place to validate requests using their keys (such as validating user-agent strings for example), the authorisation server will assume the request is genuine.