【问题标题】:Account wide Rate Limiting帐户范围的速率限制
【发布时间】:2021-06-24 17:20:20
【问题描述】:

Yii 官方文档讨论了通过在 user identity class 上实现 yii\filters\RateLimitInterface 来为 api 添加速率限制。

https://www.yiiframework.com/doc/guide/2.0/en/rest-rate-limiting

但是是否可以对非用户类实现速率限制?

例如,在我的 api 中,一个用户属于一个帐户。 一个帐户有很多用户。

是否可以按帐户而不是按用户实施速率限制?如果有怎么办?

【问题讨论】:

    标签: yii2


    【解决方案1】:

    你有两种选择如何做到这一点。

    第一个选项是在实现IdentityInterface 的同一类中实现RateLimitInterface,但在您的帐户模型中加载/存储限额。 如果您的 User 模型实现了 IdentityInterface 并具有 Account 关系,则它可能如下所示:

    class User extends ActiveRecord implements IdentityInterface, RateLimitInterface
    {
        public function getRateLimit($request, $action)
        {
            return [$this->account->rateLimit, 1]; // $rateLimit requests per second
        }
    
        public function loadAllowance($request, $action)
        {
            return [$this->account->allowance, $this->account->allowance_updated_at];
        }
    
        public function saveAllowance($request, $action, $allowance, $timestamp)
        {
            $this->account->allowance = $allowance;
            $this->account->allowance_updated_at = $timestamp;
            $this->account->save();
        }
        
        // ... the rest of User class definitions ...
    }
    

    第二种选择是让其他一些类实现RateLimitInterface,并在yii\filters\RateLimiter::$user 中使用闭包来返回该类的实例。

    【讨论】:

    • 谢谢米哈尔。您的回答是解决方案的一部分,因此我将其标记为正确。我遇到的另一个问题是allowance_updated_at 需要是一个Unix 时间戳(即一个int,而不是一个日期时间或时间戳)。最终还是不得不在我的 Api 控制器中显式调用 RateLimiter->checkRateLimit。
    • @RedTera 您链接的文档中提到了allowance_updated_at 需要是unix时间戳的事实。您必须自己调用 checkRateLimit 很奇怪。该方法由 RateLimiter 在beforeAction 中调用。您只需要将 RateLimiter 行为附加到您的控制器,并且必须在身份验证行为之后附加它,以确保在检查速率时已识别用户。这已经在yii\rest\Controller 中完成,如果你不扩展它,你必须自己设置行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 2022-08-08
    相关资源
    最近更新 更多