必须用tinker手动触发ratelimiter::hit()验证计数递增,再用postman连续发请求测429响应及x-ratelimit头,同时检查cache_driver是否为redis、throttle中间件是否前置、ip伪造是否生效。

要确认Laravel限流配置是否真实生效,必须绕过浏览器缓存、避开前端代理干扰、在可控条件下触发并观测429响应——仅靠刷新页面或写个for循环发请求,根本测不出Redis计数器是否正确递增、窗口是否滑动、重试头是否准确。
用Tinker手动触发一次限流计数
打开终端,进入项目根目录,执行php artisan tinker启动交互环境。
输入以下代码,模拟一个游客IP的登录尝试(注意替换为你实际要测试的key前缀):
$key = "login:127.0.0.1"; RateLimiter::hit($key, 60);
这行命令会向Redis写入一个带60秒TTL的计数器,并自增1。如果返回1,说明首次命中;再执行一遍,应返回2。若始终返回1,【CACHE_DRIVER未设为redis】,当前正走array驱动,所有计数都在内存里不持久、不共享、不递增。
接着验证剩余次数:RateLimiter::remaining($key, 3),传入最大允许3次。第一次运行返回2,第二次1,第三次0,第四次开始返回-1——此时已超限,但不会自动抛异常,需你主动判断。
用Postman构造四次连续请求测阈值
在Postman中新建一个GET请求,URL填你的限流接口,例如http://localhost:8000/api/test。
确保该路由已绑定throttle:3,1中间件(每分钟最多3次)。
点击「Send」发送第一次请求,观察响应状态码是200,响应头含X-RateLimit-Limit: 3、X-RateLimit-Remaining: 2。
立刻再点三次「Send」,不要停顿——第四次响应状态码必须是429 Too Many Requests,且响应头出现Retry-After: 59(数值随窗口剩余时间动态变化)。
若第四次仍是200,检查config/cache.php中default是否指向redis而非array;若429响应体为空白或不是JSON,说明你没发布自定义429响应模板,Laravel默认只返回纯文本。
用Tinker验证用户维度限流是否隔离
第一步:在Tinker中创建两个不同用户的限流key:
$user1Key = "api:user_123"; $user2Key = "api:user_456";
第二步:对user_123连续hit 5次:for($i=0; $i
第三步:检查user_123剩余次数:RateLimiter::remaining($user1Key, 5) → 返回0,确认已满。
第四步:检查user_456剩余次数:RateLimiter::remaining($user2Key, 5) → 仍返回5,证明两个用户桶完全独立。
关键点:不要用auth()->id()直接拼key,它在Tinker里无认证上下文,会返回null导致key污染。务必手动构造明确的user_id字符串。
用Postman+Header伪造IP测by=ip限流
方法一:直接修改X-Forwarded-For头
在Postman的Headers选项卡中添加键X-Forwarded-For,值填192.168.1.100;同时确保路由中间件为throttle:5,1,by=ip(Laravel 9+支持)。
方法二:改Nginx或Swoole反向代理配置(生产环境必需)
若用Nginx,确认proxy_set_header X-Forwarded-For $remote_addr;已启用,且TrustedProxy中间件已配置可信IP段,否则$request->ip()取到的是负载均衡内网地址,所有用户被归为同一IP。
发送5次请求后,第六次必须返回429;换另一个伪造IP(如192.168.1.101),应能重新获得5次额度——这才是真正的按IP隔离限流。











