Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Create your own REST API Using OAuth Authentication

This tutorial explians how to use the REST API and OAuth together in order to create a secure web service.


advertisement

As a result of more and more information being available online, information sharing between websites has become widespread. Websites usually communicate via web services — REST API is one of the technologies that can be used to create a web service. OAuth is an open standard for authorization that provides a process for end-users to authorize third-party access to their server resources without sharing their credentials (typically, a username and password pair). For example, OAuth is used when you allow a Facebook or Twitter application to use your information. In this tutorial, you will learn how to use both technologies in order to create a secure web service using REST API.

How REST API Works

An API built in REST architecture should have URLs for its resources, where the operation executed on a resource is invoked via an HTTP method. For example, an API could have the following URL for user object:

http://www.mysite.com/api/user



If an HTTP GET request is sent, the API would return user data in JSON or XML format. If a POST request is send, user data would be updated. If a POST request is sent (and the user id is not passed to the server as a parameter), a new user would be created. Finally, if a DELETE request is sent, the user with the id specified would be deleted.

Another important characteristic of the REST API architecture is to return HTTP status codes. Some of the most common codes are: 404 not found, 200 OK, 400 bad request, 401 unauthorized. See the full list of HTTP status codes here.

However, note that the following architecture is not a strict standard and that you might find slightly different implementations on the web.

How OAuth Works

OAuth is a 3-legged authorization standardthat works the following way:

  1. The consumer requests a request token (usually by passing an application key and application secret)
  2. The user is then redirected to a login page, passing the request token to that page
  3. User logs in and is redirected back to the consumer, passing the request token to the consumer's page
  4. The consumer exchanges the request token for an access token
  5. If the previous request was valid, the server will return an access token to the consumer. The access token is used for API requests

During this process, the authorization is processed using multiple predefined URLs, called endpoints. There are 3 endpoints:

  1. Request URI (this endpoint passes the request token)
  2. Access URI (exchanges request token for an access token)
  3. Authorize URI (confirms that the access token is valid)

How to Implement REST API Architecture

Creating a REST API from scratch is not an easy job. Fortunately, there are many REST API frameworks available that can be used to quickly develop your API. The simplest option is Flight framework, which is very easy to install and use. Download it and extract the files to mysite.com/api. Add the .htaccess to that folder with the following code:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L] 

All REST API routes will be created in an index.php file. For example, the following code would be executed if someone requests mysite.com/api/user :

Flight::route('/user', function(){
    echo 'This is api/user';
// Do something here
});

There are many other features and options, which you can read about in their documentation.

How to Implement OAuth Authorization Standard

For this task we will use OAuth-php library to make the development process quicker and easier. The first thing you will need to do is to allow user registration on the website. You need to generate an application key and application secret during this process. Include the following code at the end of your registration process (when the user has already been stored into the database and you can retrieve the user's id):

<?php
// Note that at the beginning of each file the OAuth-php class should be included
// You can also include this in your common file
require('../vendor/autoload.php');

// Also, the OAuth-php library uses session variables
// So, the session must be started at the beginning of each file
// Or in your common file
session_start();

$user_id = $db->lastInsertId();

$consumer = array(
    // These two are required
    'requester_name' => $_POST['name'],
    'requester_email' => $_POST['email'],

    // These are all optional
    'callback_uri' => 'http://www.mysite.com/OAuth_callback',
    'application_uri' => 'http://www.mysite.com/',
    'application_title' => 'My first application,
    'application_descr' => 'My first application dessription',
    'application_notes' => '',
    'application_type' => 'website',
    'application_commercial' => 0
);

// Register the consumer (application) and generate application key and application secret
$store = OAuthStore::instance(); 
$key   = $store->updateConsumer($consumer, $user_id);

// Get the complete consumer from the store
$consumer = $store->getConsumer($key);

$consumer_id = $consumer['id'];
$consumer_key = $consumer['consumer_key'];
$consumer_secret = $consumer['consumer_secret'];

?> 

Now, let's create the first endpoint, the one that will generate a request token and pass it to the consumer. The PHP file will be request_token.php:

<?php
$server = new OAuthServer();
$token = $server->requestToken();
exit();
?> 

The requestToken() method would validate a request for request token — it will check whether or not the user has provided a valid application key and application secret. If the request is valid, a request token will be generated and passed to the user.

The next step is to redirect the user to the login page. Let's call it authorize.php:

<?php
// Login code goes here -- check if the login is valid, fetch the user from the database etc.
// Let's assume that the login was successful and that $user_id is the id of the user that has logged in

// Instantiate OAuth classes
$store  = OAuthStore::instance();
$server = new OAuthServer();

try
{
    // Check if there is a valid request token in the current request
    // Returns an array with the consumer key, consumer secret, token, token secret and token type.
    $rs = $server->authorizeVerify();

    if ($_SERVER['REQUEST_METHOD'] == 'POST')
    {
        // See if the user clicked the 'allow' submit button (or whatever you choose)
        $authorized = array_key_exists('allow', $_POST);

        // Set the request token to be authorized or not authorized
        // When there was a OAuth_callback then this will redirect to the consumer
        $server->authorizeFinish($authorized, $user_id);

        // No OAuth_callback, show the user the result of the authorization
        // ** your code here **
   }
}
catch (OAuthException $e)
{
    // No token to be verified in the request, show a page where the user can enter the token to be verified
    // **your code here**
}
?> 

How to Connect OAuth Authorization to a REST API

Now that we know how to create a REST API and to implement OAuth authorization, let's see how to connect the two. First, we will create a function that will check if the user is authorized:

function is_authorized() {
if (OAuthRequestVerifier::requestIsSigned())
{
        try
        {
                $req = new OAuthRequestVerifier();
                $user_id = $req->verify();

                // If we have an user_id, then login as that user (for this request)
                if ($user_id)
                {
                        return true;
                }
        }
        catch (OAuthException $e)
        {
                // The request was signed, but failed verification
                header('HTTP/1.1 401 Unauthorized');
                header('WWW-Authenticate: OAuth realm=""');
                header('Content-Type: text/plain; charset=utf8');
                                        
                echo $e->getMessage();
                exit();
        }
}
}

Then we will add the following function to the REST API:

Flight::route('/user', function() {
    if(is_authorized()) {
       // User is authorized
       // Do something here
    }
});

It is good practice to place all API functions inside an PHP class, and call the authorized() function inside class constructor.



   
Vojislav Janjic has been working as a freelance web developer for more than 5 years. He is also a webmaster of two local websites.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap