简体   繁体   English

Laravel Spark - 我可以限制每月的计划 API 调用和每分钟/小时的 API 调用吗?

[英]Laravel Spark - Can I limit plan API calls per month and API calls per minute/hour?

I want to use Laravel Spark to create different licenses for an API.我想使用 Laravel Spark 为 API 创建不同的许可证。 I want to limit the API calls per month and also per hour/minute.我想限制每月以及每小时/分钟的 API 调用。 For example the Basic License will allow 10 000 monthly api calls but I also want to limit the API calls per hour/minute for the same account.例如,基本许可证将允许每月 10,000 次 API 调用,但我也想限制同一帐户每小时/分钟的 API 调用。 Can this be done with laravel spark?这可以用 laravel spark 完成吗?

There is: throttle and rate_limit, but can I limit total number of API calls per month and also per hour/minute?有:throttle 和 rate_limit,但我可以限制每月以及每小时/分钟的 API 调用总数吗? For example: 10 000 total api calls per month and max 60 api calls per hour/minute?例如:每月 10 000 次总 api 调用和每小时/分钟最多 60 次 api 调用?

According to the docs, I can limit access per minute/hour: https://laravel.com/docs/6.x/routing#rate-limiting根据文档,我可以限制每分钟/小时的访问: https ://laravel.com/docs/6.x/routing#rate-limiting

Something like this combines throttle with rate limit:像这样的东西结合了节流和速率限制:

Route::middleware('auth:api', 'throttle:10|rate_limit,1')->group(function () {     
Route::get('/user', function () { // }); 
});

But my main question is how do I combine rate limiting per minute/hour with the monthly limit?但我的主要问题是如何将每分钟/小时的速率限制与每月限制相结合?

From the same documentation page:从同一文档页面:

You may also combine this functionality with dynamic rate limits .您还可以将此功能与动态速率限制相结合。 For example, if your User model contains a rate_limit attribute, you may pass the name of the attribute to the throttle middleware so that it is used to calculate the maximum request count for authenticated users例如,如果您的User模型包含一个rate_limit属性,您可以将该属性的名称传递给throttle中间件,以便它用于计算经过身份验证的用户的最大请求数

So, given the above, you could add an accessor on your User model that gets the rate limit value based on their current subscription plan:因此,鉴于上述情况,您可以在您的User模型上添加一个访问器,该访问器根据他们当前的订阅计划获取速率限制值:

class User extends Authenticatable
{
    public function getRateLimitAttribute()
    {
        // Get license if it's a model

        if ($license === 'basic') {
            return 10000;
        }

        // Return some default here
    }
}

You can then use your dynamic rate limit value like this:然后,您可以像这样使用动态速率限制值:

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
    // Rate-limited routes
});

As for the monthly limit, you'll need to keep a counter somewhere and check that on each request.至于每月限额,您需要在某处保留一个计数器并在每次请求时进行检查。 You could log each API request in another middleware:您可以在另一个中间件中记录每个 API 请求:

class LogRequest
{
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        LogRequestJob::dispatch($request);
    }
}
class LogRequestJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function handle()
    {
        // Insert row for user to log request
        RequestLog::create([
            'user_id' => $this->request->user()->getKey(),
            'path' => $this->request->path(),
            // Store any other request data you're interested in
        ]);
    }
}

You'll then need to check the count before handling a request, again using middleware:然后,您需要在处理请求之前检查计数,再次使用中间件:

use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;

class CheckRequestInLimit
{
    public function handle($request, Closure $next)
    {
        $year = Carbon::now()->year;
        $month = Carbon::now()->month;
        $count = RequestLog::user($request->user())->year($year)->month($month)->count();
        $limit = $request->user()->monthly_limit; // another accessor

        if ($count < $limit) {
            return $next($request);
        }

        // Count is equal to (or greater than) limit; throw exception
        $retryAfter = Carbon::today()->addMonth()->startOfMonth();
        $message = 'You have exceeded your monthly limit';

        throw new TooManyRequestsHttpException($retryAfter, $message);
    }
}

Hopefully this gives you food for thought!希望这能给您带来深思!

Edit on November 1, 2021: This answer was written against an old version of Laravel. 2021 年 11 月 1 日编辑:此答案是针对旧版本的 Laravel 编写的。 Laravel later introduced rate limiting that would provide a more succinct solution to the problem above: Laravel 后来引入了速率限制,这将为上述问题提供更简洁的解决方案:

RateLimiter::for('api', function (Request $request) {
    return [
        Limit::perHour(60)->by($request->user()->getKey()),
        Limit::perDay(10000, 30)->by($request->user()->getKey()),
    ];
});

I want to use Laravel Spark to create different licenses for an API.我想使用 Laravel Spark 为 API 创建不同的许可证。 I want to limit the API calls per month and also per hour/minute.我想限制每月以及每小时/分钟的 API 调用。 For example the Basic License will allow 10 000 monthly api calls but I also want to limit the API calls per hour/minute for the same account.例如,基本许可证将允许每月 10 000 次 api 调用,但我也想限制同一帐户每小时/分钟的 API 调用。 Can this be done with laravel spark?这可以用laravel spark来完成吗?

There is: throttle and rate_limit, but can I limit total number of API calls per month and also per hour/minute?有:throttle 和 rate_limit,但我可以限制每月和每小时/分钟的 API 调用总数吗? For example: 10 000 total api calls per month and max 60 api calls per hour/minute?例如:每月总共 10 000 次 api 调用和每小时/分钟最多 60 次 api 调用?

According to the docs, I can limit access per minute/hour: https://laravel.com/docs/6.x/routing#rate-limiting根据文档,我可以限制每分钟/小时的访问: https : //laravel.com/docs/6.x/routing#rate-limiting

Something like this combines throttle with rate limit:像这样的东西结合了油门和速率限制:

Route::middleware('auth:api', 'throttle:10|rate_limit,1')->group(function () {     
Route::get('/user', function () { // }); 
});

But my main question is how do I combine rate limiting per minute/hour with the monthly limit?但我的主要问题是如何将每分钟/小时的速率限制与每月限制结合起来?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM