1 回答

TA貢獻1865條經驗 獲得超7個贊
從同一文檔頁面:
您也可以將此功能與動態速率限制結合使用。例如,如果您的User模型包含一個rate_limit屬性,您可以將屬性的名稱傳遞給throttle中間件,以便用于計算經過身份驗證的用戶的最大請求數
因此,鑒于上述情況,您可以在模型上添加一個訪問器User,該訪問器根據他們當前的訂閱計劃獲取速率限制值:
class User extends Authenticatable
{
public function getRateLimitAttribute()
{
// Get license if it's a model
if ($license === 'basic') {
return 10000;
}
// Return some default here
}
}
然后,您可以像這樣使用動態速率限制值:
Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
// Rate-limited routes
});
至于每月限額,您需要在某處保留一個柜臺,并在每個請求時檢查。您可以在另一個中間件中記錄每個 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
]);
}
}
然后,您需要在處理請求之前檢查計數,再次使用中間件:
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);
}
}
希望這能讓您深思!
2021 年 11 月 1 日編輯:此答案是針對舊版本的 Laravel 編寫的。Laravel 后來引入了速率限制,這將為上述問題提供更簡潔的解決方案:
RateLimiter::for('api', function (Request $request) {
return [
Limit::perHour(60)->by($request->user()->getKey()),
Limit::perDay(10000, 30)->by($request->user()->getKey()),
];
});
- 1 回答
- 0 關注
- 119 瀏覽
添加回答
舉報