根据官方限流器改了下,针对不同的控制器和用户进行限流,大家帮忙看下这样有问题吗?

德玛西亚

中间件代码

public function process(Request $request, callable $handler): Response
{

    $response = $handler($request);

    $user = Auth::guard('openapi_user')->user(true);

    $controllerFull = $request->controller;
    $controller = basename(str_replace('\\', '/', $controllerFull));
    $route = $controller . '@' . $request->action;
    // 定义需要特殊限流规则的路由
    $route_array = ['LoginController@test'];

    // 从配置读取默认限流参数
    $defaultLimit = (int) config('app.ratelimit.limit'); // 默认限制次数
    $ttl = (int) config('app.ratelimit.ttl'); // 限流时间窗口(秒)
    // 判断当前路由是否属于特殊限流规则
    if (in_array($route, $route_array)) {
        // 查询用户在数据库中的个性化限流配置
        $userRow = Db::table('iot_users')
            ->where('id', $user->id)
            ->first();
        // 如果用户有自定义限制则使用,否则使用默认限制
        $limit = $userRow ? (int) $userRow->limit : $defaultLimit;

        // 限流 key:特殊接口 + 用户 ID
        $key = "{$route}:{$user->id}";
    } else {
        // 非特殊接口统一限制,例如所有非特殊接口加起来最多 100 次
        $limit = 100;
        $key = "non_special:{$user->id}";
    }
    try {
        // 检查限流(如果超出限制会抛出异常)
        Limiter::check($key, $limit, $ttl, '请求过于频繁,请稍后再试');
    } catch (RateLimitException $e) {
        // 返回 429 Too Many Requests 状态码
        return response($e->getMessage(), 429);
    }
    return $response;
}
165 2 0
2个回答

tanhongbin

用万总的插件即可,很稳定,效率很高

  • 德玛西亚 4天前

    他的不支持不同的用户和不同的控制吧?

  • tanhongbin 4天前

    这种只能自己添加中间件搞比较好 要不然谁知道你的用户id怎么拿到的 有session 有jwt的各种

  • 德玛西亚 4天前

    所以我自己写了一个中间件,你也没看青我问啥。

qq7467466

// 查询用户在数据库中的个性化限流配置
这个地方搞一层缓存吧, 这样就算呗请求了也不会直接打到你的DB

🔝