PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Zend Framework 101: Zend_Oauth

Completing the OAuth Login Process

One of the configuration options for Zend_Oauth_Consumer was a callback redirect URL. This is the URL that the OAuth server (Twitter in this case) redirects the user back to after they've authenticated and approved the consumer application.

In our application we've called this script callback.php. In addition to using the request tokens we stored in login.php, the user is redirected to callback.php with an authorization token which we use to retrieve an access token from Twitter.

Listing 8 shows how we begin the callback script. We start by ensuring the request tokens exist in the session data. If they're not the script will fall through and output an "invalid request" message (I'll include this shortly). We then recreate the Zend_Oauth_Token_Request object so we can retrieve the access token.

Listing 8 Building a request token from session data (listing-8.php)
<?php
    require_once('globals.php');
    require_once('Zend/Session.php');
 
    $session = new Zend_Session_Namespace('twitter_oauth');
 
    if (strlen($session->token) > 0 && strlen($session->secret) > 0) {
        require_once('Zend/Oauth/Consumer.php');
 
        // build the token request based on the original token and secret
        $request = new Zend_Oauth_Token_Request();
        $request->setToken($session->token)
                ->setTokenSecret($session->secret);
?>

Next we use the Zend_Oauth_Consumer class to retrieve an access token. To do so, we use the getAccessToken() method. This method will throw an exception if a valid access token cannot be retrieved, so we wrap this entire block in a "try catch".

When calling getAccessToken() we pass the request token as well the authorization token that was passed back when the user was redirected. The authorization token is stored in "get" data. Therefore we can simply pass $_GET, as shown in Listing 9.

Listing 9 Retrieving the access token from Twitter (listing-9.php)
<?php
        try {
            // try to retrieve the token
            $consumer = new Zend_Oauth_Consumer(getAuthConfig());
            $token = $consumer->getAccessToken($_GET, $request);
?>

At this stage we have an access token with which we can access the Twitter API. We will now write this to our previously created database table (doing so means the getTwitterAccessToken() will now have data to return). Listing 10 shows how we can write this data.

Listing 10 Saving the access token to the database (listing-10.php)
<?php
            // we now have a token, insert into database
            $values = array(
                'user_id' => getUserId(),
                'token'   => $token->getToken(),
                'secret'  => $token->getTokenSecret()
            );
 
            $db->insert('twitter_auth', $values);
?>

Finally we must clean up and finish off the request, as shown in Listing 11. To clean up we simply remove the request token and secret stored in the session data. We then redirect the user back to protected script (index.php - we'll create this shortly).

Additionally, we're going to handle the exception that may be thrown by getAccessToken(), as well as output a message if the session data wasn't found. Currently the exception handler has been left blank. You can substitute in your own logic (or logging) as required, but otherwise it will just fall through to the error message that is output.

Listing 11 Cleaning up the OAuth request (listing-11.php)
<?php
            // clear the request tokens from session
            unset($session->token);
            unset($session->secret);
 
            // return to protected page
            header('Location: index.php');
            exit;
        }
        catch (Exception $ex) {
            // error retrieving token, handle accordingly
        }
    }
?>
 
<p>
    Invalid callback request, please try again.
</p>
 
<p>
    <a href="login.php">Log in</a>
</p>

The complete callback.php script is shown in Listing 12.

Listing 12 The full callback script to complete the OAuth request (callback.php)
<?php
    require_once('globals.php');
    require_once('Zend/Session.php');
 
    $session = new Zend_Session_Namespace('twitter_oauth');
 
    if (strlen($session->token) > 0 && strlen($session->secret) > 0) {
        require_once('Zend/Oauth/Consumer.php');
 
        // build the token request based on the original token and secret
        $request = new Zend_Oauth_Token_Request();
        $request->setToken($session->token)
                ->setTokenSecret($session->secret);
 
        try {
            // try to retrieve the token
            $consumer = new Zend_Oauth_Consumer(getAuthConfig());
            $token = $consumer->getAccessToken($_GET, $request);
 
            // we now have a token, insert into database
            $values = array(
                'user_id' => getUserId(),
                'token'   => $token->getToken(),
                'secret'  => $token->getTokenSecret()
            );
 
            $db->insert('twitter_auth', $values);
 
            // clear the request tokens from session
            unset($session->token);
            unset($session->secret);
 
            // return to protected page
            header('Location: index.php');
            exit;
        }
        catch (Exception $ex) {
            // error retrieving token, handle accordingly
        }
    }
?>
 
<p>
    Invalid callback request, please try again.
</p>
 
<p>
    <a href="login.php">Log in</a>
</p>

Finally we will implement the protected page (index.php). This script allows the authenticated user to post a message to their Twitter timeline.

In This Article