YII2 Framework RESTful API format response, authorization authentication and rate limiting three parts detailed _php example

Source: Internet
Author: User
Tags auth findone oauth php class php and yii


Before writing a YII2 framework to create a restful-style API QuickStart tutorial, go on to explore YII2 RESTful's formatted response, authorization certification and rate limiting three parts



First, directory structure


List the files you want to change first. The directory is as follows:


Web
├─common
│└─models 
│└user.php
└─frontend
├─config
│└main.php />└bookcontroller.php


Second, formatted response


YII2 restful supports JSON and XML formats, and if you want to specify the format for returning data, you need to configure the Yii\filters\contentnegotiator::formats property. For example, to return to JSON format, modify frontend/controllers/bookcontroller.php, and add the Red Markup code:


namespace Frontend\controllers;
Use Yii\rest\activecontroller;
Use Yii\web\response;
Class Bookcontroller extends Activecontroller
{public
$modelClass = ' Frontend\models\book ';
Public Function Behaviors () {
$behaviors = parent::behaviors ();
$behaviors [' Contentnegotiator '] [' formats '] [' text/html '] = Response::format_json;
return $behaviors;
}


Returns the XML format: Format_xml. The keys of the Formats property support MIME types, and values must support the response format name in Yii\web\response::formatters.



Third, authorized certification


RESTful APIs are usually stateless, so each request should be accompanied by some kind of authorization voucher, that is, each request sends an access token to authenticate the user.



1. Configure the User application component (not necessary, but recommended configuration):

Set the Yii\web\user::enablesession property to False (because the restful APIs are stateless, and when Yii\web\user::enablesession is false, The user authentication status in the request cannot be persisted by session



Set the Yii\web\user::loginurl property to Null (displays an HTTP 403 error instead of jumping to the login interface)



Specifically, modify the frontend/config/main.php and add the Red Tag code:


' Components ' => [
...
] User ' => ['
identityclass ' => ' common\models\user ',
' Enableautologin ' => true,
' enablesession ' = > False,
' loginurl ' => null,
],
...
]


2. Configure the authenticator behavior in the controller class to specify which authentication method to use, modify the frontend/controllers/bookcontroller.php, and add the Red Tag code:

namespace frontend \ controllers;
use yii \ rest \ ActiveController;
use yii \ web \ Response;
use yii \ filters \ auth \ CompositeAuth;
use yii \ filters \ auth \ QueryParamAuth;
class BookController extends ActiveController
{
public $ modelClass = 'frontend \ models \ Book';
public function behaviors () {
$ behaviors = parent :: behaviors ();
$ behaviors ['authenticator'] = [
'class' => CompositeAuth :: className (),
'authMethods' => [
/ * Below are three ways to verify access_token * /
// 1. HTTP basic authentication: The access token is sent as a user name. It is used in scenarios where the access token can be safely stored in the API client. For example, the API client is a program running on a server.
// HttpBasicAuth :: className (),
//2.OAuth 2: The user obtains the access token based on the OAuth2 protocol from the authentication server, and then sends it to the API server through HTTP Bearer Tokens.
// HttpBearerAuth :: className (),
// 3. Request parameters: The access token is sent as an API URL request parameter. This method should be mainly used for JSONP requests because it cannot send access tokens using HTTP headers
// http: // localhost / user / index / index? access-token = 123
QueryParamAuth :: className (),
],
];
$ behaviors ['contentNegotiator'] ['formats'] ['text / html'] = Response :: FORMAT_JSON;
return $ behaviors;
}
}


3. Create a user table

-----------------------------
-Table structure for user
-----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int (10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar (20) NOT NULL DEFAULT '' COMMENT 'user name',
`password_hash` varchar (100) NOT NULL DEFAULT '' COMMENT 'password',
`password_reset_token` varchar (50) NOT NULL DEFAULT '' COMMENT 'password token',
`email` varchar (20) NOT NULL DEFAULT '' COMMENT 'mailbox',
`auth_key` varchar (50) NOT NULL DEFAULT '',
`status` tinyint (3) unsigned NOT NULL DEFAULT '0' COMMENT 'status',
`created_at` int (10) unsigned NOT NULL DEFAULT '0' COMMENT 'creation time',
`updated_at` int (10) unsigned NOT NULL DEFAULT '0' COMMENT 'update time',
`access_token` varchar (50) NOT NULL DEFAULT '' COMMENT 'restful request token',
`allowance` int (10) unsigned NOT NULL DEFAULT '0' COMMENT 'restful number of remaining allowed requests',
`allowance_updated_at` int (10) unsigned NOT NULL DEFAULT '0' COMMENT 'restful request number of UNIX timestamp'
PRIMARY KEY (`id`),
UNIQUE KEY `username` (` username`),
UNIQUE KEY `access_token` (` access_token`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
-----------------------------
-Records of user
-----------------------------
INSERT INTO `user` VALUES ('1', 'admin', '$ 2y $ 13 $ 1KWwchqGvxDeORDt5pRW.OJarf06PjNYxe2vEGVs7e5amD3wnEX.i', '', '', 'z3sM2KZvXdk6mNXXrz3D, 3', 123 ',' 4 ',' 1478686493 ');


Implement the Yii\web\identityinterface::findidentitybyaccesstoken () method in the Common/models/user.php class. To modify common/models/user.php, add the Red tag code::




public static function findIdentityByAccessToken ($ token, $ type = null)
{
// The implementation of findIdentityByAccessToken () method is system defined
// For example, in a simple scenario, when each user has only one access token, the access token can be stored in the access_token column of the user table, and the method can be simply implemented in the User class, as shown below:
return static :: findOne (['access_token' => $ token]);
// throw new NotSupportedException ('"findIdentityByAccessToken" is not implemented.');
}

 Fourth. Rate Limit





To prevent abuse, the rate limit can be increased. For example, restricting the use of APIs per user is a maximum of 10 API calls in 60 seconds, and if too many requests are received for a user within the same time period, the response status Code 429 (which means too many requests) is returned.





1.Yii automatically uses Yii\filters\ratelimiter to configure a behavior filter for Yii\rest\controller to perform a rate limit check. If the speed exceeds the limit, the rate limiter throws a yii\web\toomanyrequestshttpexception.



To modify frontend/controllers/bookcontroller.php, add the red tag code:


namespace frontend \ controllers;
use yii \ rest \ ActiveController;
use yii \ web \ Response;
use yii \ filters \ auth \ CompositeAuth;
use yii \ filters \ auth \ QueryParamAuth;
use yii \ filters \ RateLimiter;
class BookController extends ActiveController
{
public $ modelClass = 'frontend \ models \ Book';
public function behaviors () {
$ behaviors = parent :: behaviors ();
$ behaviors ['rateLimiter'] = [
'class' => RateLimiter :: className (),
'enableRateLimitHeaders' => true,
];
$ behaviors ['authenticator'] = [
'class' => CompositeAuth :: className (),
'authMethods' => [
/ * Below are three ways to verify access_token * /
// 1. HTTP basic authentication: The access token is sent as a user name. It is used in scenarios where the access token can be safely stored in the API client. For example, the API client is a program running on a server.
// HttpBasicAuth :: className (),
//2.OAuth 2: The user obtains the access token based on the OAuth2 protocol from the authentication server, and then sends it to the API server through HTTP Bearer Tokens.
// HttpBearerAuth :: className (),
// 3. Request parameters: The access token is sent as an API URL request parameter. This method should be mainly used for JSONP requests because it cannot send access tokens using HTTP headers
// http: // localhost / user / index / index? access-token = 123
QueryParamAuth :: className (),
],
];
$ behaviors ['contentNegotiator'] ['formats'] ['text / html'] = Response :: FORMAT_JSON;
return $ behaviors;
}
}


2. Use two columns in the user table to record tolerance and timestamp information. To improve performance, consider using caching or NoSQL to store this information.


To modify common/models/user.php, add the red tag code:


namespace common \ models;
use Yii;
use yii \ base \ NotSupportedException;
use yii \ behaviors \ TimestampBehavior;
use yii \ db \ ActiveRecord;
use yii \ web \ IdentityInterface;
use yii \ filters \ RateLimitInterface;
class User extends ActiveRecord implements IdentityInterface, RateLimitInterface
{
....
// Return the maximum number of requests allowed per unit time, for example, [10, 60] means that at most 10 requests within 60 seconds.
public function getRateLimit ($ request, $ action)
{
return [5, 10];
}
// Return the number of remaining allowed requests.
public function loadAllowance ($ request, $ action)
{
return [$ this-> allowance, $ this-> allowance_updated_at];
}
// The UNIX timestamp when saving the request.
public function saveAllowance ($ request, $ action, $ allowance, $ timestamp)
{
$ this-> allowance = $ allowance;
$ this-> allowance_updated_at = $ timestamp;
$ this-> save ();
}
....
public static function findIdentityByAccessToken ($ token, $ type = null)
{
// throw new NotSupportedException ('"findIdentityByAccessToken" is not implemented.');
// The implementation of findIdentityByAccessToken () method is system defined
// For example, in a simple scenario, when each user has only one access token, the access token can be stored in the access_token column of the user table, and the method can be simply implemented in the User class, as follows:
return static :: findOne (['access_token' => $ token]);
}
....
} }


The above is a small series to introduce the YII2 framework RESTful API format response, authorization certification and speed limit three parts of the detailed explanation, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.