The following example demonstrates how to program a PHP application to perform an authorization code grant using OAuth 2.0. It assumes knowledge of HTTP, PHP 5.0+, and a passing knowledge of the cUrl library for PHP.

Compared with OAuth 1.0, OAuth 2.0 greatly simplifies the authentication process. With OAuth 1.0, developers either had to rely upon a third party library for issuing OAuth requests, or else write custom code for generating the encrypted signatures required for each request. By contrast, OAuth 2.0 requests can be made using a few simple calls to the cUrl library in PHP.

As discussed in Getting Started, an authorization code grant in OAuth 2.0 consists of the following steps:

  1. The client (in this case, our PHP application) requests an access code. Elance responds with a redirection URL to which the client must send the user, so that the user can authenticate her account credentials.
  2. Once the user has granted permissions for the client to access her account, the Elance server calls a callback URL on the client with the access code as a GET parameter.
  3. The callback URL on the client sends the cient ID, client secret, and access code to Elance and exchanges it for an access token. This access token can then be used in subsequent API calls.

tableofcontents_number_textThe Elance Authentication Class

To simplify coding and reduce redundancy, we have encapsulated most of the code for this example in a PHP class called ElanceAuthentication. The ElanceAuthentication class consists of three main methods:

  • InitCurl(): A private method that calls the cUrl library function curl_init() and configures the cUrl connection.
  • RequestAccessCode(): A public method that requests the access token. The argument to this method is the URL of our callback script. This method simply returns an API URL, to which our script will then redirect the user using an HTTP 307 Location redirect.
  • GetAccessToken(): A public method that exchanges the access code for an access token. The arguments to this method include the client ID and client secret, as well as the access code that Elance supplies when it calls our PHP callback script. The return value from this method is a JSON object containing the access token, as well as other information.

 

To use this file, copy and save it into a file name elance-auth-lib.php either in the same directory as your PHP application, or somewhere in your PHP library path.

<?php
 
class ElanceAuthentication {
    public $CurlHeaders;
    public $ResponseCode;
 
    private $_AuthorizeUrl = "https://api.elance.com/api2/oauth/authorize";
    private $_AccessTokenUrl = "https://api.elance.com/api2/oauth/token";
 
    public function __construct() {
        $this->CurlHeaders = array();
        $this->ResponseCode = 0;
    }
 
    public function RequestAccessCode ($client_id, $redirect_url) {
        return($this->_AuthorizeUrl . "?client_id=" . $client_id . "&response_type=code&redirect_uri=" . $redirect_url);
    }
 
    // Convert an authorization code from an Elance callback into an access token.
    public function GetAccessToken($client_id, $client_secret, $auth_code) {        
        // Init cUrl.
        $r = $this->InitCurl($this->_AccessTokenUrl);
 
        // Add client ID and client secret to the headers.
        curl_setopt($r, CURLOPT_HTTPHEADER, array (
            "Authorization: Basic " . base64_encode($client_id . ":" . $client_secret),
        ));        
 
        // Assemble POST parameters for the request.
        $post_fields = "code=" . urlencode($auth_code) . "&grant_type=authorization_code";
 
        // Obtain and return the access token from the response.
        curl_setopt($r, CURLOPT_POST, true);
        curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
 
        $response = curl_exec($r);
        if ($response == false) {
            die("curl_exec() failed. Error: " . curl_error($r));
        }
 
        //Parse JSON return object.
        return json_decode($response);
    }
 
    private function InitCurl($url) {
        $r = null;
 
        if (($r = @curl_init($url)) == false) {
            header("HTTP/1.1 500", true, 500);
            die("Cannot initialize cUrl session. Is cUrl enabled for your PHP installation?");
        }
 
        curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
 
        // Decode compressed responses.
        curl_setopt($r, CURLOPT_ENCODING, 1);
 
        // NOTE: If testing locally, add the following lines to use a dummy certificate, and to prevent cUrl from attempting to verify
        // the certificate's authenticity. See http://richardwarrender.com/2007/05/the-secret-to-curl-in-php-on-windows/ for more
        // details on this workaround. If your server has a valid SSL certificate installed, comment out these lines.
        curl_setopt($r, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($r, CURLOPT_CAINFO, "C:\wamp\bin\apache\Apache2.2.21\cacert.crt");
 
        // NOTE: For Fiddler2 debugging.
        //curl_setopt($r, CURLOPT_PROXY, '127.0.0.1:8888');
 
        return($r);
    }
 
    // A generic function that executes an Elance API request. 
    public function ExecRequest($url, $access_token, $get_params) {
        // Create request string.
        $full_url = http_build_query($url, $get_params);
 
        $r = $this->InitCurl($url);
 
        curl_setopt($r, CURLOPT_HTTPHEADER, array (
            "Authorization: Basic " . base64_encode($access_token)
        ));
 
        $response = curl_exec($r);
        if ($response == false) {
            die("curl_exec() failed. Error: " . curl_error($r));
        }
 
        //Parse JSON return object.
        return json_decode($response);        
    }
}
 
?>

tableofcontents_number_textRequesting User Authentication

To obtain the access code, we write a small PHP script that calls the RequestAccessCode() method. This returns a URL to which we redirect the user.

<?php
 
require_once('elance-auth-lib.php');
 
error_reporting(E_ALL);
 
$elance_auth = new ElanceAuthentication();
$url = $elance_auth->RequestAccessCode("4eb1de8bf06b10210e000005", "http://yourdomainname.com/elance/callback.php");
 
header("Location: " . $url);
 
?>

tableofcontents_number_textThe callback.php Script

After Elance has authenticated the user, it will call our callback.php script with the access code supplied as the code parameter in the query string. Our script passes this access code to the GetAccessToken() method of the ElanceAuthentication class. The response from Elance will be a JSON object containing several properties, including the access_token property.

Our simple example below simply prints out the access token; a real-world application will keep this value private, and store it securely on the server for use in subsequent Elance Developer API requests.

<?php
 
require_once('elance-auth-lib.php');
 
if (!isset($_GET["code"])) {
    die("Require the code parameter to validate!");
}
 
$code = $_GET["code"];
$elance_auth = new ElanceAuthentication();
$json = $elance_auth->GetAccessToken("4eb1de8bf06b10210e000005", "M5IqdtQdZN8cX741OkBniA", $code);
 
//Output code
echo "Access token is " . $json->data->access_token . "<p/>";
 
?>