Aug 15 2011

Implementing Twitter sign-in with Silex and PHP

Set-up

  • Install pecl oauth
  • Grab the Silex .phar archive
  • Create a Twitter application

pecl oauth

Install the pecl oauth extension

For example:

$ pecl install oauth

Silex

For those not acquainted with Silex:

Silex is a PHP microframework for PHP 5.3

A microframework provides the guts for building simple single-file apps.

It's awesome.

All you need is the silex.phar file and you're away. Download it.

For the example, I've setup a virtual host of example.local on my development machine. The apache module mod_rewrite and a .htaccess file are used to rewrite requests to index.php.

# .htaccess
<IfModule mod_rewrite.c>
    Options -MultiViews

    RewriteEngine On
    #RewriteBase /path/to/app
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

Create a Twitter application

Create a Twitter app

Once you've created your application, you'll need your consumer key and consumer secret. These are used to sign every request made to the API.

Implementation

A complete summary along with a pretty diagram of what we're trying to achieve can be found here.

Basic OAuth request cycle:

  • Retrieve a request token
  • Request authorization
  • Exchange the request token for an access token

More information - https://dev.twitter.com/docs/auth/oauth

Basic Silex application

// index.php
define('CONS_KEY', 'Application consumer key');
define('CONS_SECRET', 'Application consumer secret');

require_once __DIR__.'/silex.phar'; 

$app = new Silex\Application(); 

// register the session extension
$app->register(new Silex\Extension\SessionExtension());

$app->get('/', function() use($app) { 
    $username = $app['session']->get('username');

    if ($username == null) {
        return 'Welcome Guest. <a href="/login">Login</a>'; 
    } else {
        return 'Welcome ' . $app->escape($username);
    }
}); 

$app->run(); 

Add the /login route

The first part of the process requires the retrieval of a request token. Authorization is requested by redirecting to https://twitter.com/oauth/authenticate.

// index.php
$app->get('/login', function () use ($app) {
    // check if the user is already logged-in
    if (null !== ($username = $app['session']->get('username'))) {
        return $app->redirect('/');
    }

    $oauth = new OAuth(CONS_KEY, CONS_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
    $request_token = $oauth->getRequestToken('https://twitter.com/oauth/request_token');

    $app['session']->set('secret', $request_token['oauth_token_secret']);

    return $app->redirect('https://twitter.com/oauth/authenticate?oauth_token=' . $request_token['oauth_token']);
});

Add the /auth route

In my example setup the URL would be http://example.local/auth. Set your Twitter application callback URL in the app settings to be the auth route.

Within this action, the request token is exchanged with the access token which allows usage of the Twitter API on behalf of the user.

// index.php
$app->get('/auth', function() use ($app) {
    // check if the user is already logged-in
    if (null !== ($username = $app['session']->get('username'))) {
        return $app->redirect('/');
    }

    $oauth_token = $app['request']->get('oauth_token');

    if ($oauth_token == null) {
        $app->abort(400, 'Invalid token');
    }

    $secret = $app['session']->get('secret');

    $oauth = new OAuth(CONS_KEY, CONS_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
    $oauth->setToken($oauth_token, $secret);

    try {
        $oauth_token_info = $oauth->getAccessToken('https://twitter.com/oauth/access_token');
    } catch (OAuthException $e) {
        $app->abort(401, $e->getMessage());
    }

    // retrieve Twitter user details
    $oauth->setToken($oauth_token_info['oauth_token'], $oauth_token_info['oauth_token_secret']);
    $oauth->fetch('https://twitter.com/account/verify_credentials.json');
    $json = json_decode($oauth->getLastResponse());

    $app['session']->set('username', $json->screen_name);

    return $app->redirect('/');
});

Resources

  • Comments [4]
Tue, 16 Aug 2011 02:55:15 +0100

Is there something missing from the last code example? Your /auth controller's closure uses $pdo, but it isn't used to persist the oauth access token.

Ade
Tue, 16 Aug 2011 10:09:36 +0100

Good spot. I do use PDO to persist the oauth access token but removed it for the examples to reduce the amount of code. Have updated the gist and blog post.

Bill Ortell
Sun, 30 Oct 2011 16:26:33 +0000

Thanks, Ade (@Jeremy Mikola - nice catch too)! Great example... was looking for something similar but lighter yet from ninjauth... any of you got that incorp'd into the Silex as a package?

Bill

John
Tue, 28 Feb 2012 08:19:22 +0000

Hi Ade,

Many thanks for the tutorial.

I actually came here from google searching for examples on using PDO storage for Sliex sessions and I see you mention this in the comment above but have removed the original references!

I can't find any clear information on how to do this anywhere. Any guidance would be massively appreciated! Cheers

  • Leave a comment

Markdown format

Not published anywhere or shared with anyone

 
 

Info

I'm Ade Slade, a PHP web developer.