You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel:如何仅对未认证API用户启用请求限流?

Laravel API 仅对未认证用户启用请求限流的实现方案

刚好之前做项目遇到过一模一样的需求,给你分享两种靠谱的实现方式,看哪种更适配你的业务场景:

方案一:拆分API路由组(逻辑清晰,推荐)

这种方式是把未认证和已认证的API路由分开,分别绑定不同的中间件组,精准控制限流范围。

步骤1:修改Kernel中的中间件组配置

打开app/Http/Kernel.php,在$middlewareGroups里新增一个专门给未认证用户用的api:guest组,把限流规则放在这里;原api组去掉限流,留给已认证用户使用:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    'api' => [
        // 移除原throttle,仅保留必要的绑定替换中间件
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    'api:guest' => [
        // 未认证用户的限流规则:每分钟240次请求
        'throttle:240,1',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

步骤2:拆分API路由

打开routes/api.php,把路由分成未认证和已认证两组,分别绑定对应的中间件:

use App\Http\Controllers\AuthController;
use Illuminate\Http\Request;

// 未认证用户可访问的路由(登录、注册等),使用api:guest中间件组
Route::middleware('api:guest')->group(function () {
    Route::post('/login', [AuthController::class, 'login']);
    Route::post('/register', [AuthController::class, 'register']);
    // 其他公开API路由都放这里
});

// 已认证用户专属路由,使用api+auth:api中间件组(无限制)
Route::middleware(['api', 'auth:api'])->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
    // 所有需要登录才能访问的API路由放这里
});

方案二:自定义限流中间件(更灵活)

如果不想拆分路由,也可以自定义一个中间件,自动判断用户是否认证,仅对未认证用户触发限流。

步骤1:生成自定义中间件

执行Artisan命令生成中间件:

php artisan make:middleware ThrottleUnauthenticatedUsers

步骤2:编写中间件逻辑

打开app/Http/Middleware/ThrottleUnauthenticatedUsers.php,继承Laravel原生的限流中间件,重写handle方法:

<?php

namespace App\Http\Middleware;

use Illuminate\Routing\Middleware\ThrottleRequests;

class ThrottleUnauthenticatedUsers extends ThrottleRequests
{
    public function handle($request, \Closure $next, $maxAttempts = 60, $decayMinutes = 1)
    {
        // 如果用户已认证,直接跳过限流
        if ($request->user()) {
            return $next($request);
        }

        // 未认证用户,执行原生限流逻辑
        return parent::handle($request, $next, $maxAttempts, $decayMinutes);
    }
}

步骤3:注册中间件别名

回到app/Http/Kernel.php,在$routeMiddleware里注册自定义中间件的别名:

protected $routeMiddleware = [
    // 其他原有中间件...
    'throttle.guest' => \App\Http\Middleware\ThrottleUnauthenticatedUsers::class,
];

步骤4:替换原API中间件组的限流规则

修改$middlewareGroups里的api组,把原throttle:240,1替换成自定义的throttle.guest:240,1:

'api' => [
    'throttle.guest:240,1',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

这样所有API路由都会通过这个自定义中间件,自动识别用户状态,仅对未认证用户执行限流。

两种方案都能实现你的需求,第一种拆分路由的方式逻辑更直观,适合路由划分清晰的项目;第二种自定义中间件的方式更灵活,适合不想改动现有路由结构的场景。

内容的提问来源于stack exchange,提问作者Aontaigh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:37:51