You are viewing revision #2 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
- Useful Tools
- Create a web services controller
- Actions
- Authentication
- Table to store authentication data
- 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.
- Open poster from tools (ctrl+alt+P)
- Provide url for webservice i.e http://www.example.com/index.php?r=site/heartbeat
- Add parameter username as "test" and password as "xyz"
- Click on content to send and choose content options as "Body from Parameters"
- 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.
Alternate method also documented
Hi
I have documented my method (not as well documented, but different method):
http://www.yiiframework.com/wiki/607/how-to-use-token-based-authentication/
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.