侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解

框架(架构)  /  管理员 发布于 7年前   220

之前写过一篇Yii2框架制作RESTful风格的API快速入门教程,今天接着来探究一下Yii2 RESTful的格式化响应,授权认证和速率限制三个部分

一、目录结构

先列出需要改动的文件。目录如下:

web├─ common│ └─ models │ └ User.php└─ frontend├─ config│ └ main.php└─ controllers└ BookController.php

二、格式化响应

Yii2 RESTful支持JSON和XML格式,如果想指定返回数据的格式,需要配置yii\filters\ContentNegotiator::formats属性。例如,要返回JSON格式,修改frontend/controllers/BookController.php,加入红色标记代码:

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;}}

返回XML格式:FORMAT_XML。formats属性的keys支持MIME类型,而values必须在yii\web\Response::formatters中支持被响应格式名称。

三、授权认证

RESTful APIs通常是无状态的,因此每个请求应附带某种授权凭证,即每个请求都发送一个access token来认证用户。

1.配置user应用组件(不是必要的,但是推荐配置):

  设置yii\web\User::enableSession属性为false(因为RESTful APIs为无状态的,当yii\web\User::enableSession为false,请求中的用户认证状态就不能通过session来保持)

  设置yii\web\User::loginUrl属性为null(显示一个HTTP 403 错误而不是跳转到登录界面)

具体方法,修改frontend/config/main.php,加入红色标记代码:

'components' => [...'user' => ['identityClass' => 'common\models\User','enableAutoLogin' => true,'enableSession' => false,'loginUrl' => null,],...]

2.在控制器类中配置authenticator行为来指定使用哪种认证方式,修改frontend/controllers/BookController.php,加入红色标记代码:

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' => [/*下面是三种验证access_token方式*///1.HTTP 基本认证: access token 当作用户名发送,应用在access token可安全存在API使用端的场景,例如,API使用端是运行在一台服务器上的程序。//HttpBasicAuth::className(),//2.OAuth 2: 使用者从认证服务器上获取基于OAuth2协议的access token,然后通过 HTTP Bearer Tokens 发送到API 服务器。//HttpBearerAuth::className(),//3.请求参数: access token 当作API URL请求参数发送,这种方式应主要用于JSONP请求,因为它不能使用HTTP头来发送access token//http://localhost/user/index/index?access-token=123QueryParamAuth::className(),],];$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON;return $behaviors;}}

3.创建一张user表

-- ------------------------------ 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 '用户名',`password_hash` varchar(100) NOT NULL DEFAULT '' COMMENT '密码',`password_reset_token` varchar(50) NOT NULL DEFAULT '' COMMENT '密码token',`email` varchar(20) NOT NULL DEFAULT '' COMMENT '邮箱',`auth_key` varchar(50) NOT NULL DEFAULT '',`status` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '状态',`created_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',`updated_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',`access_token` varchar(50) NOT NULL DEFAULT '' COMMENT 'restful请求token',`allowance` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'restful剩余的允许的请求数',`allowance_updated_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'restful请求的UNIX时间戳数',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', '1478686493', '1478686493', '123', '4', '1478686493');

在common/models/User.php类中实现 yii\web\IdentityInterface::findIdentityByAccessToken()方法。修改common/models/User.php,加入红色标记代码::

public static function findIdentityByAccessToken($token, $type = null){//findIdentityByAccessToken()方法的实现是系统定义的//例如,一个简单的场景,当每个用户只有一个access token, 可存储access token 到user表的access_token列中, 方法可在User类中简单实现,如下所示:return static::findOne(['access_token' => $token]);//throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');}

四、速率限制

为防止滥用,可以增加速率限制。例如,限制每个用户的API的使用是在60秒内最多10次的API调用,如果一个用户同一个时间段内太多的请求被接收,将返回响应状态代码 429 (这意味着过多的请求)。

1.Yii会自动使用yii\filters\RateLimiter为yii\rest\Controller配置一个行为过滤器来执行速率限制检查。如果速度超出限制,该速率限制器将抛出一个yii\web\TooManyRequestsHttpException。

修改frontend/controllers/BookController.php,加入红色标记代码:

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' => [/*下面是三种验证access_token方式*///1.HTTP 基本认证: access token 当作用户名发送,应用在access token可安全存在API使用端的场景,例如,API使用端是运行在一台服务器上的程序。//HttpBasicAuth::className(),//2.OAuth 2: 使用者从认证服务器上获取基于OAuth2协议的access token,然后通过 HTTP Bearer Tokens 发送到API 服务器。//HttpBearerAuth::className(),//3.请求参数: access token 当作API URL请求参数发送,这种方式应主要用于JSONP请求,因为它不能使用HTTP头来发送access token//http://localhost/user/index/index?access-token=123QueryParamAuth::className(),],];$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON;return $behaviors;}}

2.在user表中使用两列来记录容差和时间戳信息。为了提高性能,可以考虑使用缓存或NoSQL存储这些信息。

修改common/models/User.php,加入红色标记代码:

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{....// 返回在单位时间内允许的请求的最大数目,例如,[10, 60] 表示在60秒内最多请求10次。public function getRateLimit($request, $action){return [5, 10];}// 返回剩余的允许的请求数。public function loadAllowance($request, $action){return [$this->allowance, $this->allowance_updated_at];}// 保存请求时的UNIX时间戳。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.');//findIdentityByAccessToken()方法的实现是系统定义的//例如,一个简单的场景,当每个用户只有一个access token, 可存储access token 到user表的access_token列中, 方法可在User类中简单实现,如下所示:return static::findOne(['access_token' => $token]);}....}

以上所述是小编给大家介绍的Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!

您可能感兴趣的文章:

  • PHP实现支持GET,POST,Multipart/form-data的HTTP请求类
  • php处理restful请求的路由类分享
  • 通过JS和PHP两种方法判断用户请求时使用的浏览器类型
  • php自定义类fsocket模拟post或get请求的方法
  • 解读PHP的Yii框架中请求与响应的处理流程
  • YII2框架中使用yii.js实现的post请求
  • yii2 在控制器中验证请求参数的使用方法
  • Yii框架通过请求组件处理get,post请求的方法分析
  • Yii 框架控制器创建使用及控制器响应操作示例
  • Yii框架响应组件用法实例分析
  • YII Framework学习之request与response用法(基于CHttpRequest响应)
  • PHP封装请求类实例分析【基于Yii框架】


  • 上一条:
    Yii2实现log输出到file及database的方法
    下一条:
    Yii2框架制作RESTful风格的API快速入门教程
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客