首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii2 RESTful API 深度实战:响应格式化、认证授权与速率限制

     編輯:PHP 綜合知識

概述

Yii2 内置强大的 RESTful 支持,本文系统讲解三大核心功能的配置与最佳实践:响应格式化、认证授权、速率限制。基于 Yii 2.0 版本,代码可直接用于生产环境。

目录结构

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

一、响应格式化

Yii2 通过 yii\filters\ContentNegotiator 支持 JSON、XML 等格式。默认根据 Accept 头自动协商,也可强制指定。

控制器配置示例

<?php
namespace frontend\controllers;

use yii\rest\ActiveController;
use yii\web\Response;
use yii\filters\ContentNegotiator;

class BookController extends ActiveController
{
    public $modelClass = 'frontend\models\Book';

    public function behaviors()
    {
        $behaviors = parent::behaviors();

        // 重新配置 contentNegotiator
        $behaviors['contentNegotiator'] = [
            'class' => ContentNegotiator::class,
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
                'application/xml'  => Response::FORMAT_XML,
                // 强制浏览器访问也返回 JSON(可选)
                'text/html' => Response::FORMAT_JSON,
            ],
        ];

        return $behaviors;
    }
}

测试验证

  • GET /books → 返回 JSON 数组
  • GET /books?format=xml → 返回 XML(需额外解析 query 参数)
  • 或发送 Header: Accept: application/xml

二、认证授权

RESTful API 无状态,每次请求需携带凭证。Yii2 提供三种内置认证方式:

方式类适用场景
HTTP Basic AuthHttpBasicAuth服务器间通信,access token 作用户名
OAuth 2 (Bearer Token)HttpBearerAuth标准 OAuth2 流程,Header 传递 Authorization: Bearer <token>
Query ParamQueryParamAuthJSONP 或无法设置 Header 的场景,?access-token=xxx

1. 配置 User 组件(关键)

// frontend/config/main.php
'components' => [
    'user' => [
        'identityClass' => 'common\models\User',
        'enableAutoLogin' => false,   // 无状态 API 禁用自动登录
        'enableSession' => false,     // 禁用 Session,避免 CSRF 等问题
        'loginUrl' => null,           // 直接返回 403 而非重定向登录页
    ],
],

2. 控制器挂载认证行为

public function behaviors()
{
    $behaviors = parent::behaviors();

    $behaviors['authenticator'] = [
        'class' => \yii\filters\auth\CompositeAuth::class,
        'authMethods' => [
            \yii\filters\auth\HttpBearerAuth::class,  // 推荐:Bearer Token
            \yii\filters\auth\QueryParamAuth::class,  // 兼容:Query 参数
        ],
        'except' => ['options'], // OPTIONS 请求跳过认证(CORS 预检)
    ];

    return $behaviors;
}

3. User 模型实现 findIdentityByAccessToken()

// common/models/User.php
namespace common\models;

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{
    // ... 其他方法 ...

    public static function findIdentityByAccessToken($token, $type = null)
    {
        // 简单场景:token 存数据库 user 表的 access_token 字段
        return static::findOne(['access_token' => $token, 'status' => 10]);
    }
}

4. 数据库表结构参考

CREATE TABLE `user` (
  `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `username` VARCHAR(50) NOT NULL UNIQUE,
  `password_hash` VARCHAR(255) NOT NULL,
  `access_token` VARCHAR(100) NOT NULL UNIQUE COMMENT 'API 访问令牌',
  `auth_key` VARCHAR(32) NOT NULL,
  `status` SMALLINT UNSIGNED DEFAULT 10,
  `created_at` INT UNSIGNED DEFAULT 0,
  `updated_at` INT UNSIGNED DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

三、速率限制

防止滥用,限制单位时间内请求次数。Yii2 通过 yii\filters\RateLimiter 实现,需身份类实现 RateLimitInterface。

1. User 模型实现限流接口

use yii\filters\RateLimitInterface;

class User extends ActiveRecord implements IdentityInterface, RateLimitInterface
{
    // ... 现有字段需包含 allowance, allowance_updated_at ...

    // 返回 [最大请求数, 时间窗口秒数] 例:1分钟内最多60次
    public function getRateLimit($request, $action)
    {
        return [60, 60];
    }

    // 返回 [剩余配额, 最后更新 Unix 时间戳]
    public function loadAllowance($request, $action)
    {
        return [$this->allowance, $this->allowance_updated_at];
    }

    // 保存更新后的配额与时间戳
    public function saveAllowance($request, $action, $allowance, $timestamp)
    {
        $this->allowance = $allowance;
        $this->allowance_updated_at = $timestamp;
        $this->save(false, ['allowance', 'allowance_updated_at']);
    }
}

2. 控制器挂载 RateLimiter

public function behaviors()
{
    $behaviors = parent::behaviors();

    $behaviors['rateLimiter'] = [
        'class' => \yii\filters\RateLimiter::class,
        'enableRateLimitHeaders' => true, // 返回 X-Rate-Limit-* 头
    ];

    // 认证配置...
    return $behaviors;
}

3. 响应头示例

X-Rate-Limit-Limit: 60
X-Rate-Limit-Remaining: 59
X-Rate-Limit-Reset: 1699999999

超限时自动抛出 yii\web\TooManyRequestsHttpException (HTTP 429)。

性能优化建议

  • 高并发场景:将 allowance 存 Redis,避免每次请求写数据库。
  • 分布式部署:RateLimiter 依赖统一存储,Redis 是最佳选择。
  • 白名单:在 getRateLimit() 中根据用户角色返回不同限额,或直接返回 [INF, 1] 跳过限流。

完整控制器示例

<?php
namespace frontend\controllers;

use yii\rest\ActiveController;
use yii\web\Response;
use yii\filters\ContentNegotiator;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
use yii\filters\RateLimiter;

class BookController extends ActiveController
{
    public $modelClass = 'frontend\models\Book';

    public function behaviors()
    {
        $behaviors = parent::behaviors();

        // 1. 格式化
        $behaviors['contentNegotiator'] = [
            'class' => ContentNegotiator::class,
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
                'application/xml'  => Response::FORMAT_XML,
            ],
        ];

        // 2. 认证
        $behaviors['authenticator'] = [
            'class' => CompositeAuth::class,
            'authMethods' => [
                HttpBearerAuth::class,
                QueryParamAuth::class,
            ],
            'except' => ['options'],
        ];

        // 3. 限流
        $behaviors['rateLimiter'] = [
            'class' => RateLimiter::class,
            'enableRateLimitHeaders' => true,
        ];

        return $behaviors;
    }
}

结语

通过组合 ContentNegotiator、CompositeAuth、RateLimiter,Yii2 能快速构建生产级 RESTful API。关键点在于:禁用 Session、正确实现 IdentityInterface 与 RateLimitInterface、合理配置限流策略。建议结合 Redis 优化高并发下的限流性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved