Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!

Lorna Jane Mitchell is a PHP developer, blogger, trainer and evangelist from Leeds in the UK. She is active with phpwomen.org and her local user group PHP North West, and writes for a variety of outlets, including her own blog at lornajane.net. She is an active member of the PHP and open source communities and contributes to the joind.in event feedback project. When she's not at her computer, Lorna enjoys yarn craft, hobby electronics, and her home renovation project. Lorna is a DZone MVB and is not an employee of DZone and has posted 33 posts at DZone. You can read more from them at their website. View Full User Profile

PHP OAuth Provider: Access Tokens

09.03.2011
Email
Views: 3027
  • submit to reddit

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 has already started to be adopted (and differs greatly). This article uses the pecl_oauth extension and builds on Rasmus' OAuth Provider post. This entry follows on from the ones about the initial requirements, how to how to handle request tokens, and authenticating users.

Here we're performing the final step in the handshake to grant access; giving an access token. To achieve this, the consumer makes a request and includes:

  • consumer key and secret
  • request token and secret
  • verifier token

This basically means that we know who they are, that they did send the user to us and the user went back to them.

My PHP code for this step looks something like this, with $db, $request_token and verifier already in place, and following the same provider block to check the request as was shown in the request token post:

// bin 2 hex because the binary isn't friendly
        $access_token = bin2hex($this->provider->generateToken(8));
        $access_token_secret = bin2hex($this->provider->generateToken(16));
        // get request data
        $request_sql = 'select authorised_user_id as user_id
            from oauth_request_tokens
            where request_token = :request_token
            and verification = :verifier';
        try {
            $request_stmt = $db->prepare($request_sql);
            $request_response = $request_stmt->execute(array(
                "request_token" => $request_token,
                "verifier" => $verifier
                ));
            $request_data = $request_stmt->fetch();
            if($request_data) {
                // now delete this token, it shouldn't be used again
                $delete_sql = 'delete from oauth_request_tokens
                    where request_token = :request_token';
                $delete_stmt = $db->prepare($delete_sql);
                $delete_stmt->execute(array('request_token' => $request_token));
            } else {
                error_log('request token not found');
                return false;
            }
        } catch (PDOException $e) {
            error_log('Could not retrieve/delete request token data ' . $e->getMessage());
            return false;
        }
        // store new access token
        $sql = 'insert into oauth_access_tokens set '
            . 'access_token = :access_token,'
            . 'access_token_secret = :access_token_secret,'
            . 'consumer_key = :consumer_key, '
            . 'user_id = :user_id';
        try{
            $stmt = $db->prepare($sql);
            $stmt->execute(array(
                "consumer_key" => $this->provider->consumer_key,
                "access_token" => $access_token,
                "access_token_secret" => $access_token_secret,
                "user_id" => $request_data['user_id']));
            return array('oauth_token' => $access_token,
                'oauth_token_secret' => $access_token_secret);
        } catch(PDOException $e) {
            error_log('Could not insert access token ' . $e->getMessage());
            return false;
        }

The calling code checks that it gets an array in response, with the new token and secret in it. If it does, we need to return those to the OAuth consumer, and exactly as when we did the request token, we do this by simply echoing a query string:
echo "oauth_token=" . $tokens['oauth_token'] . '&oauth_token_secret=' . $tokens['oauth_token_secret'];

At this point we have shaken hands, and the consumer has an access token they can use to make "normal" calls as an authenticated user. I'll add one final entry to this series to show the use of the tokens in association with a standard web service.

References
Tags:
Published at DZone with permission of Lorna Mitchell, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)