Yii2 framework RESTful API format response, authorization authentication, and rate limit
I have previously written a quick start tutorial on creating RESTful APIs in the Yii2 framework. Today I want to explore the format response, authorization authentication, and Rate limiting of Yii2 RESTful APIs.
I. directory structure
First, list the files to be modified. The directory is as follows:
web├─ common│ └─ models │ └ User.php└─ frontend├─ config│ └ main.php└─ controllers└ BookController.php
Ii. format the response
Yii2 RESTful supports JSON and XML formats. to specify the format of returned data, you must configure the yii \ filters \ ContentNegotiator: formats attribute. For example, to return the JSON format, modify frontend/controllers/BookController. php and add the Red Flag 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;}}
The returned XML format is FORMAT_XML. The keys of the formats attribute supports the MIME type, while values must support the Response format name in yii \ web \ Response: formatters.
Iii. Authorization
RESTful APIs is usually stateless. Therefore, each request should be accompanied by an authorization credential, that is, each request sends an access token to authenticate the user.
1. Configure the user application component (not necessary, but recommended ):
Set the yii \ web \ User: enableSession attribute to false (because RESTful APIs is stateless, when yii \ web \ User: enableSession is false, the user authentication status in the request cannot be maintained through the session)
Set the yii \ web \ User: loginUrl attribute to null (an HTTP 403 error is displayed instead of jumping to the logon interface)
For details, modify frontend/config/main. php and add the Red Flag Code:
'components' => [...'user' => ['identityClass' => 'common\models\User','enableAutoLogin' => true,'enableSession' => false,'loginUrl' => null,],...]
2. Configure the authenticator action in the Controller class to specify the authentication method used, modify frontend/controllers/BookController. php, and add the Red Flag 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 '=> [/* There are three types of verification Access_token Method * // 1. HTTP Basic Authentication: an access token is sent as a user name. An access token can be securely used in API scenarios. For example, an API user is a program running on a server. // HttpBasicAuth: className (), // 2. OAuth 2: the user obtains the access token Based on the oau2protocol from the authentication server, and then sends it to the API server through HTTP Bearer Tokens. // HttpBearerAuth: className (), // 3. request Parameter: access token is sent as an api url request parameter. This method should be mainly used for JSONP requests because it cannot use an HTTP header to send access token // http: // localhost/user/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 'username', '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 ', 'allowant' int (10) unsigned not null default '0' COMMENT 'number of allowed requests remaining in restful ', 'allowance _ updated_at' int (10) unsigned not null default '0' comment' Number of UNIX timestamps of restful requests ', 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 ', '','', 'z3sm2kzvxdk6mnxxrz25d3jozlgxojmc', '10', '123', '123', '123', '4', '123', '123 ');
Implement the yii \ web \ IdentityInterface: findIdentityByAccessToken () method in the common/models/User. php class. Modify common/models/User. php and add the red tag code ::
Public static function findIdentityByAccessToken ($ token, $ type = null) {// The Implementation of The findIdentityByAccessToken () method is defined by the system. // 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. The method can be implemented in the user class as follows: return static :: findOne (['Access _ token' => $ token]); // throw new NotSupportedException ('"findIdentityByAccessToken" is not implemented. ');}
Iv. Speed Limit
To prevent abuse, you can increase the speed limit. For example, each user's API is limited to a maximum of 10 API calls within 60 seconds. If a user receives too many requests within the same time period, code 429 of the response status will be returned (this means too many requests ).
1. Yii automatically uses yii \ filters \ RateLimiter to configure an action filter for yii \ rest \ Controller to perform the rate limit check. If the speed exceeds the limit, a yii \ web \ TooManyRequestsHttpException is thrown.
Modify frontend/controllers/BookController. php and add the Red Flag 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 (), 'en AbleRateLimitHeaders '=> true,]; $ behaviors ['authenticator'] = ['class' => CompositeAuth: className (), 'authmethods '=> [/* There are three methods to verify access_token * // 1. HTTP Basic Authentication: an access token is sent as a user name. An access token can be securely used in API scenarios. For example, an API user is a program running on a server. // HttpBasicAuth: className (), // 2. OAuth 2: the user obtains the access token Based on the oau2protocol from the authentication server, and then sends it to the API server through HTTP Bearer Tokens. // HttpBearerAuth: className (), // 3. request Parameter: access token is sent as an api url request parameter. This method should be mainly used for JSONP requests because it cannot use an HTTP header to send access token // http: // localhost/user/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 the tolerances and timestamp information. To improve performance, you can consider using cache or NoSQL to store this information.
Modify common/models/User. php and add the Red Flag 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] indicates a maximum of 10 requests within 60 seconds. Public function getRateLimit ($ request, $ action) {return [5, 10] ;}// returns the remaining allowed requests. Public function loadAllowance ($ request, $ action) {return [$ this-> allowance, $ this-> allowance_updated_at];} // UNIX timestamp used to save 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 The findIdentityByAccessToken () method is defined by the system. // For example, in a simple scenario, when each user has only one access token, you can store access tokens in the access_token column of the user table. The method can be implemented in the User class as follows: return static :: findOne (['Access _ token' => $ token]);}...}
The above section describes how to format and respond to the Yii2 framework RESTful API, authorize authentication, and speed limit. I hope this will help you. If you have any questions, please leave a message, the editor will reply to you in a timely manner. Thank you very much for your support for the help House website!