thinkphp api限流需正确配置throttle或ratelimit中间件、启用redis缓存、透传真实ip、nginx前置限流及手动滑动窗口实现,缺一不可。

如果您在使用ThinkPHP开发API接口时,发现请求被恶意刷量或需控制用户调用频次,则可能是由于未正确配置访问频率限制机制。以下是实现API访问频率限制的多种可行方法:
一、使用Throttle中间件配置IP级限流
Throttle中间件是ThinkPHP 6生态中开箱即用的限流方案,底层依赖Cache驱动,支持按客户端IP进行固定窗口计数。其生效前提是中间件已注册并显式挂载到目标路由。
1、执行命令安装扩展:composer require topthink/think-throttle
2、确认config/throttle.php已存在;若无,运行php think vendor:publish发布配置文件
3、在app/middleware.php中启用全局中间件开关:'use_global_middleware' => true
4、在app/route/app.php中,对API路由分组绑定中间件:Route::group('api', function () { /* 路由定义 */ })->middleware('throttle:60,1');
5、注意visit_rate格式必须为整数加单位,如'10/m',不可写为'3/15s';第二个参数为分钟单位,支持小数(如0.5表示30秒)
二、通过RateLimit中间件实现自定义键限流
RateLimit中间件默认按IP限流,但可通过继承重写getLimitedId()方法,将限流粒度精确到用户ID、接口路径或组合标识,避免多路由共享同一计数器的问题。
1、新建中间件类app/http/middleware/UserRateLimit.php,继承think\middleware\RateLimit
2、重写getLimitedId()方法,返回唯一业务标识:return $request->userId() ?: $request->ip().'_'.$request->rule();
3、在路由中显式调用该中间件:->middleware('app\http\middleware\UserRateLimit:100,0.5')
4、确保config/cache.php中default驱动已设为'redis',防止文件缓存因锁竞争导致计数不准
三、在Nginx层配置前置限流规则
Nginx限流可在请求抵达PHP之前拦截高频请求,降低后端压力,适用于基础防护场景,尤其适合应对CC攻击或突发流量。
1、在nginx.conf的http块中添加限流区域:limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/s;
2、在server或location块中引用该区域,允许突发缓冲:limit_req zone=api_limit burst=40 nodelay;
3、针对特定API路径(如/api/)单独配置,避免影响静态资源
4、重启Nginx使配置生效:systemctl reload nginx
四、基于Redis手动实现滑动窗口限流
手动编码可完全掌控限流逻辑,支持滑动窗口算法,精度高于固定窗口,适用于需严格防突增的高敏感接口,如登录、短信发送等。
1、编写工具函数api_visits(),使用Redis的psetex命令设置毫秒级过期:Cache::psetex("user_{$uid}_api_{$action}", $ttl, 1);
2、在控制器中调用该函数判断是否受限:if (!api_visits('login_verify', 500, $uid)) { return $this->error('接口访问频繁,请稍后再试'); }
3、确保phpredis扩展已启用,且Redis服务正常运行
4、key命名须带业务前缀,如'throttle:api:login:' . md5($ip),避免跨应用冲突
五、修复IP获取不准确导致的限流失效
在Nginx + PHP-FPM架构下,$request->ip()常返回127.0.0.1,致使所有请求被识别为同一IP,限流形同虚设。必须透传并清洗真实客户端IP。
1、检查Nginx配置是否包含以下两行:proxy_set_header X-Real-IP $remote_addr; 和 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2、新建中间件app/middleware/CheckIp.php,在请求进入前覆盖IP头:$request = $request->withHeader('X-Real-IP', $request->header('x-real-ip'));
3、在app/middleware.php中注册该中间件,并确保其执行顺序早于throttle或ratelimit中间件
4、对X-Forwarded-For字段做清洗,仅取逗号分隔后的第一个公网IP,丢弃内网地址和无效段
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











