Tuesday, February 11, 2014
Securing your RESTful web services
Web services are usually exposed to developers so that developers can create cool things consuming the API. Here, for the web service developer security is a big concern. Malicious coders may try to find any vulnerability. If some vulnerability is found your API is simply insecure.
An API which needs to bee accessed by authenticated users may require request level authentication mechanism. Passing user unique identity and password with each request is very dangerous. Instead an access token sort of thing must be used. The md5 and hash encryption is your best friend in this regard.
I assume that you have basic idea of MVC framework, and the sample code will be Yii based. We will utilize the power of OOP in Yii framework. You can download and learn Yii from here.
In my previous tutorial I put some lines on creating RESTful web services. Here, we are simply extending that code to add the security features.
Let suppose our API is for authenticated users. Each request made to the API will be processed after authentication. A user, first time, usually logs in with a username and password. When the user is authenticated we will return a hash encrypted string to be used as access token with future requests.
The code in your login action will be something like this.
public function actionLogin(){
$data = CJSON::decode(file_get_contents('php://input')); /*get the JSON body*/
/* Implement some authentication*/
/*if authenticated update the users table with the latest access token.*/
$access_token = md5($data["username"] . rand(10000, 9999999));
}
The client will get the access token that may be an Android, iPhone, web or mobile application. The client stores this access token and will pass it with every request they will make in the future.
So on each controller action execution this access token will be validated.
Here we will use the power of event handling in Yii framework.
method in base class ie "RestController"
public function beforeAction($action) {
//access tocken validation
}
//calling any action of this controller will raise the
//beforeAction of the base calass
}
An API which needs to bee accessed by authenticated users may require request level authentication mechanism. Passing user unique identity and password with each request is very dangerous. Instead an access token sort of thing must be used. The md5 and hash encryption is your best friend in this regard.
I assume that you have basic idea of MVC framework, and the sample code will be Yii based. We will utilize the power of OOP in Yii framework. You can download and learn Yii from here.
In my previous tutorial I put some lines on creating RESTful web services. Here, we are simply extending that code to add the security features.
Let suppose our API is for authenticated users. Each request made to the API will be processed after authentication. A user, first time, usually logs in with a username and password. When the user is authenticated we will return a hash encrypted string to be used as access token with future requests.
The code in your login action will be something like this.
public function actionLogin(){
$data = CJSON::decode(file_get_contents('php://input')); /*get the JSON body*/
/* Implement some authentication*/
/*if authenticated update the users table with the latest access token.*/
$access_token = md5($data["username"] . rand(10000, 9999999));
}
The client will get the access token that may be an Android, iPhone, web or mobile application. The client stores this access token and will pass it with every request they will make in the future.
So on each controller action execution this access token will be validated.
Here we will use the power of event handling in Yii framework.
Example secure method
method in base class ie "RestController"
public function beforeAction($action) {
//access tocken validation
}
API Controller:
class myAPI extends RestController {//calling any action of this controller will raise the
//beforeAction of the base calass
}
How it works:
myAPI controller is extended from RestController which has an event handler beforeAction. Withe each action call within controllers extended from this class will cause the beforeAction to be executed. Here we can put some secure security checks. Like access token validation, IP constraints etc.
Wednesday, January 1, 2014
clean and pretty RESTful web services in Yii/JSON
What is a web Serice
Web services have gained booming adaptation for distributed computing. After the mobile computing era its significant has been much more increased.
Unlike traditional client/server models, such as a Web server/Web page system, Web services do not provide the user with a GUI. Web services instead share business logic, data and processes through a programmatic interface across a network. The applications interface, not the users. Developers can then add the Web service to a GUI (such as a Web page or an executable program) to offer specific functionality to users.
is REST an API?
Actually REST is the http. Roy Fielding described REST in his Ph.D dissertation. You do not need to use any sort of library like we used to use in SOAP based web services.
So yes in terms of the architecture and no in term of application.
So yes in terms of the architecture and no in term of application.
REST is just a mechanism to interact with the server regardless of platform.
How we built pretty restful web services?
Yeah! You know JQuery says: "Write less do more" and Yii says "Write a line and leave rest on Yii". With the combination of Yii and JQuery the web service design becomes more efficient and scalable. Yii is the fastest and efficient PHP framework and JQuery is the most popular JavaScript framework.
Hello World!
What you want to do first is to write the "hello world" thing. Not only you we all! Without doing code kastoori we will write a clean API.Introduction to Yii
Yii is getting more popular among than any other PHP frameworks. Yii attracts smart developers due to its clean and component based MVC pattern.Yii introduces many features and advance oop techniques which are not available in any existing PHP framework. This tutorial assumes that you already know the basics of Yii framework.
Base conroller for our API
As every Yii controller is inherited from CController. We will create our own base controller which will be inherited from CController.class ApiController extends CController{
//Functionality
}
In the ApiConroller we will put all we needed functionality. One of this functionality we need is the generation of output i,e the JSON.
protected function sendResponse($status = 200, $body = '', $contentType = 'application/json')
{
// Set the status
$statusHeader = 'HTTP/1.1 ' . $status . ' ' . $this->getStatusCodeMessage($status);
header($statusHeader);
// Set the content type
header('Content-type: ' . $contentType);
echo $body;
Yii::app()->end();
}
To send appropriate headers also we put the function getStatusCodeMessage which assigns the status code in the JSON header. And the definition of this function goes here:
protected function getStatusCodeMessage($status)
{
$codes = array(
100 => 'Continue',
101 => 'Switching Protocols',
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
203 => 'Non-Authoritative Information',
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Found',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
306 => '(Unused)',
307 => 'Temporary Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
406 => 'Not Acceptable',
407 => 'Proxy Authentication Required',
408 => 'Request Timeout',
409 => 'Conflict',
410 => 'Gone',
411 => 'Length Required',
412 => 'Precondition Failed',
413 => 'Request Entity Too Large',
414 => 'Request-URI Too Long',
415 => 'Unsupported Media Type',
416 => 'Requested Range Not Satisfiable',
417 => 'Expectation Failed',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported',
420 => 'Error'
);
return (isset($codes[$status])) ? $codes[$status] : '';
}
Now, we will inherit all our controllers from this base class ApiController. Suppose we have a student Model which posses all student related information such as ID, Name, grade etc. So we are going to write a service which will return all users with all info.
class StudentController extends ApiController{
public function actionStudents(){
$students = Students::model()->findAll();
$this->sendResponse(200,CJSON::encode($students));
}
}
Line by line analysis:
1- StudentController is inherited from ApiController which has the sendResponse function2- The Student action which will be pointed by a URI.
3- A student object is initiated which has all student info
4- Sends the response in JSON string.
The CJSON::enchod() will convert the student object into JSON string. In our case the output string will be
[
{"id":"15","name":"Shahid","grade":"10"},
{"id":"16","name":"Kate","grade":"9"},
]
Well, the intelligent CJSON::encode() function have converted the student object into JSON array very cleanly.
To test your API hit http://localhost/yourservice/index.php/student/students
Hope you enjoyed!
Subscribe to:
Posts
(Atom)