PHP REST Services

PHP REST Services

RESTful web service API framework for PHP

Authentication & Authorization

A Little Theory

Authentication is the mechanism used by software systems to securely identify their users.
Authorization is the mechanism that provides what level of access a certain system user should have.
Currently, many systems are using username and password pairs in order to authenticate their users and this is the case for our package also.

WiseLoop PHP REST Services offers a very nice out-of-the-box implementation of these concepts, while also leaving the flexibility of implementing own security mechanisms.
In order to add security support for an API, one should define an auth handler that will describe the authentication & authorization mechanisms for the API:

class myAuthHandler extends wlAuthHandler {
    public function authenticate($authData){
        //authenticate $authData and array or an object that should contain the username and password to be authenticated
    }
    public function isAuthorized($request) {
        //authorize the $request
    }
}

An auth handler should be derived from wlAuthHandler and should overwrite wlAuthHandler::authenticate and wlAuthHandler::isAuthorized methods.
Method wlAuthHandler::isAuthorized should return bool and takes as parameter the current request; see wlRestRequest for more information.

To enable authentication, the auth handler must be instantiated and used inside wlRestControllerAuth that should be registered in within our service:

$authHandler = new myAuthHandler();
$service->registerController(new wlRestControllerAuth($authHandler));

To enable authorization, the auth handler must be instantiated and used inside a trigger registered in our service at request time:

$service->registerTrigger(new wlRestTriggerAuth($authHandler), wlRestTrigger::ON_REQUEST_EVENT);

Now, each incoming request will be validated by the handler wlAuthHandler::isAuthorized method.

For convenience, the package contains a few built-in and ready to be used auth handlers that provides authentication for username / password credentials provided by different means:

Please check the corresponding documentation of each handler for more details.
To enable authorization also, it's a good idea to create a new auth handler by inheriting the built-in one and specify own authorization logic by overwriting the wlAuthHandler::isAuthorized method.

Note:
Please be aware that user management (create, update, delete users and maintain passwords) is beyond the actual authentication and authorization concepts and the package do not offer such functionality out of the box. You can easily create a new controller that can handle user management for your own very specific case.

1. Securing your API using a trigger

The most common and the recommended way of securing your API is by using a trigger registered at on-request time.

Example. Authentication & authorization for users stored in a MySQL database

The database

Let's suppose we have a local MySQL database called my_database and the table where the credentials are stored is called users.
To access the database we will user the following credentials: 'root' for the username and 'secret' for the password.
The users table consists of the following fields:

  • username (string)
  • password (string and hashed with md5)
  • fullName (string)
  • is_admin (bool)
  • is_editor (bool)

We want to build an API that will authenticate against the users table and authorize some CRUD operation depending on is_admin and is_editor fields.

The auth handler

class myAuthHandler extends wlAuthHandlerPdoMySql {
    public function isAuthorized($request) {
        //here, the $authData will be an associative array with the fields taken from the database table: username, is_admin, is_editor (without password)
        $authData = $this->get();
        $isAdmin = $authData['is_admin'];
        $isEditor = $authData['is_editor'];
        $fullName = $authData['fullName'];

        //implement own authorization logic ...
        $controller = $request->getControllerName();
        if($controller == 'post' && ($isAdmin || $isEditor)) {
            return true;
        }elseif($controller == 'user' && $isAdmin) {
            return true;
        }
        return parent::isAuthorized($request);
    }
 }

In this sample the authorization logic is dependent on the controller name of the request and it is written directly inside the isAuthorized method. This logic can be more complex dependent on other request parameters such as method or payload and for a cleaner code it can be written in external helpers or call external methods. It is really up to you how this logic should be implemented as PHP Rest Services offers this authorization wrapper around the requests.

Registering the auth handler in within the API service

After registering the handler with the service API you want to build through the wlRestControllerAuth controller and enable authorization through triggers, the framework will take care of everything:

//create the service object
$service = new wlRestService();
// ... register API controllers, output handlers, triggers etc.

//instantiate the auth handler
$authHandler = new myAuthHandler('localhost', 'my_database', 'root', 'secret', 'users', 'username', 'password', true);
$service->registerController(new wlRestControllerAuth($authHandler));
$service->registerTrigger(new wlRestTriggerAuth($authHandler), wlRestTrigger::ON_REQUEST_EVENT);

//run the service
$service->run();

Please check the Creating REST Services for more information regarding the creation of a basic API. The commercial package includes a fully functional demo that can serve as a very good sample for implementing security for you API.

Accessing the secured API

After registering the auth handler using the wlRestControllerAuth controller, our API will be enriched with a few more routes dealing with the authentication mechanism:

  • POST http ://rest-service-endpoint-url/auth/v1/login: must have as payload the following fields: userName and password; call this route tu authenticate a user
  • POST http ://rest-service-endpoint-url/auth/v1/logout: when calling this the current user logout
  • GET http ://rest-service-endpoint-url/auth/v1/user: will return the all the information available for the current logged user
  • GET http ://rest-service-endpoint-url/auth/v1/user/some-field: will return the specified field value of the current logged user (ex. http ://rest-service-endpoint-url/auth/v1/user/fullName)

Please check the full included sample to see an actual secured API implementation.
Of course, you are free to extend the basic wlRestControllerAuth, change the default 'auth' name, add new routes (maybe for user management) and use your controller for authentication mechanism.

2. Securing API using route-level authorization

Although it is the recommended way, one can find unhandy implementing the full authorization mechanism in a single method wlAuthHandler::isAuthorized as described above.
Fortunately, PHP Rest Services provides also another way of authorization mechanism specified at controller route level:

class someController extends wlRestController {
    public function getDefaultName() {
        return 'some';
    }

    protected function nameGetAllowed() {
        $params = $this->actionParams;
        // ... any logic here
        return true; //false
    }
    protected function nameGet() {
        return array('my-name' => 'John');
    }
}

Basically, this is a convention that of you want to validate a certain route, you need to suffix it's corresponding method with 'Allowed'. The suffixed 'Allowed' method will be evaluated before the actual route method that will be executed only if the evaluation result is true. If false, the API call will return 403 Forbidden status.
Because the route validation take place at the method level, if you opt for this authorization method, there is no need to register any trigger like described in the previous chapter.

Of course, you can combine the two authorization methods to suit your needs.

Regular License $10.00
Use by you or one client, in a single end product which end users are not charged for.

Extended License $50.00
Use by you or one client, in a single end product which end users can be charged for.

Short Information

Building a RESTful web service for your PHP web application has never been so easy!
WiseLoop PHP REST Services is a powerful API framework that allows easy development of any kind of API through RESTful web services.

Buyer rating:
338 Sales