How-To: Create Token Authenticated Web Services

  1. Useful Tools
  2. Create a web services controller
  3. Actions
  4. Authentication
  5. Table to store authentication data
  6. Test WebService

This article is about implementing authentication to Yii based web services.

In this article we shall cover authentication for POST requests For other request code can be modified easily.

Useful Tools

To test these web services you can use the [Firefox Poster Addon] (https://addons.mozilla.org/en-US/firefox/addon/poster/).

Create a web services controller

Create a new Site Controller

class SiteController extends Controller {

    public $layout = false;

    /**
     * @return array action filters
     */
    public function filters() {
        return array(
            'postOnly + heartbeat',
        );
    }

    /**
     * This is the action to handle external exceptions.
     */
    public function actionError() {
        if ($error = Yii::app()->errorHandler->error) {


            $filterErrorArray = array(
                'code' => $error['code'],
                'errorCode' => $error['errorCode'],
                'message' => $error['message'],
            );

            if (Yii::app()->params['apidebug']) {
                $filterErrorArray['type'] = $error['type'];
                $filterErrorArray['file'] = $error['file'];
                $filterErrorArray['line'] = $error['line'];
            }


            echo CJSON::encode($filterErrorArray);
        }
    }

    public function actionHeartBeat() {
        $code = '00';
        $message = 'Heartbeat Successful';
        echo CJSON::encode(array(
            'code' => $code,
            'message' => $message
        ));
    }

}

Actions

Handling errors
public function actionError() {
     .....
}

This function will show error information in JSON output. Put a flag in params to manage what data should be shown to responses in different modes.

Web Service test function
public function actionHeartBeat() {
   ......

}

Test function to check if web service is working or not.

Authentication

I have here used a bit tricky method for authentication. Yii core have functionality to handle CSRF protection. In web services all the requests from another server so we do't need this functionality. We can override this to authenticate clients requests.

Override HTTPRequest

Create new file HttpRequest.php in components

<?php

/*
 * This file contain the code to  use custom Http Request instead of Yii's Automatic request
 */

class HttpRequest extends CHttpRequest {

    public $tokenName = 'password';
    public $appName = 'username';

    public function authenticateApp($params) {

        $attributes = array(
            'token' => trim($params['token']),
            'name' => trim($params['name']),
            'status' => 1
        );


        $tokemExists = App::model()->findByAttributes($attributes);

        if ($tokemExists) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Overrided it to use apptoken.
     */
    public function validateCsrfToken($event) {
        if ($this->getIsPostRequest()) {

           
            if (isset($_POST[$this->tokenName]) && isset($_POST[$this->appName])) {

                $params = array(
                    'token' => $_POST[$this->tokenName],
                    'name' => $_POST[$this->appName]
                );

                $valid = $this->authenticateApp($params);
            } else {
                $valid = false;
            }

            if (!$valid) {
                if (isset(Yii::app()->user->id)) {
                    Yii::app()->user->logout();
                }

                throw new CHttpException(400, Yii::t('yii', 'Authentication failed.'));
            }
        }
    }

}

?>

Whenever there is post request it will trigger the authentication function for the request.

Add config in main.php

To enable this token add following to components.

'components' => array(
  ........
                'request' => array(
                    'class' => 'application.components.HttpRequest',
                    'enableCsrfValidation' => true,
                ),
.........
)

Table to store authentication data

Create a new table to store web service authentication data.

CREATE TABLE IF NOT EXISTS `tbl_app` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(200) DEFAULT NULL,
  `token` varchar(500) DEFAULT NULL,
  `status` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;


INSERT INTO `tbl_app` (`id`, `name`, `token`, `status`) VALUES
(1, 'test', 'xyz', 1);

Generate model using Gii for this table.

Test WebService

Below are the steps to test Webservices by Poster Firefox add on.

  1. Open poster from tools (ctrl+alt+P)
  2. Provide url for webservice i.e http://www.example.com/index.php?r=site/heartbeat
  3. Add parameter username as "test" and password as "xyz"
  4. Click on content to send and choose content options as "Body from Parameters"
  5. Post the request.

Note:- We are using this authentication services for our web services. It may not be the best practice to authenticate web services. Your comments are welcomed.

4 0
17 followers
Viewed: 27 641 times
Version: 1.1
Category: How-tos
Written by: hemc
Last updated by: CeBe
Created on: Dec 28, 2013
Last updated: 4 years ago
Update Article

Revisions

View all history

Related Articles