为了防止滥用,您应该考虑为您的 API 添加限流。例如,您可能希望将每个用户的 API 使用限制在 10 分钟内最多 100 次 API 调用。如果在指定时间段内从用户那里收到太多请求,则应返回状态代码为 429(表示“请求过多”)的响应。
要启用限流,用户身份类 应实现 yii\filters\RateLimitInterface。此接口需要实现三种方法
getRateLimit()
:返回允许的最大请求数和时间段(例如,[100, 600]
表示在 600 秒内最多可以有 100 次 API 调用)。loadAllowance()
:返回允许的剩余请求数以及上次检查速率限制时对应的 Unix 时间戳。saveAllowance()
:保存允许的剩余请求数和当前 Unix 时间戳。您可能希望在用户表中使用两列来记录配额和时间戳信息。定义好这些后,就可以实现 loadAllowance()
和 saveAllowance()
来读取和保存与当前已认证用户对应的两列的值。为了提高性能,您还可以考虑将这些信息存储在缓存或 NoSQL 存储中。
在 User
模型中的实现可能如下所示
public function getRateLimit($request, $action)
{
return [$this->rateLimit, 1]; // $rateLimit requests per second
}
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();
}
一旦身份类实现了所需的接口,Yii 将自动使用 yii\filters\RateLimiter(配置为 yii\rest\Controller 的操作过滤器)来执行限流检查。当速率限制超出时,速率限制器将抛出 yii\web\TooManyRequestsHttpException。
您可以在 REST 控制器类中按如下方式配置速率限制器
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
return $behaviors;
}
启用限流后,默认情况下,每个响应都将发送以下包含当前限流信息的 HTTP 标头
X-Rate-Limit-Limit
,允许的最大请求数和时间段X-Rate-Limit-Remaining
,当前时间段内剩余的请求数X-Rate-Limit-Reset
,为了获得允许的最大请求数需要等待的秒数您可以通过将 yii\filters\RateLimiter::$enableRateLimitHeaders 配置为 false
来禁用这些标头,如上述代码示例所示。
发现错别字或您认为此页面需要改进?
在 GitHub 上编辑 !
请注册或登录以发表评论。