限流与防重复提交
实现位于 src/core/RateLimit。无需单独 registry:只要路由配置了 rateLimit / repeatSubmit(或对应装饰器),且 Redis 可用即生效。
执行时机:鉴权之后、业务 Handler 之前。
@RateLimiter
ts
import { RateLimiter, RateLimiterType, PostController } from '@/core/Application'
@PostController('/get/:id')
@RateLimiter({ time: 10, count: 3, type: RateLimiterType.IP })
get(@RequestPath() id: string) {
return this.userService.getUser(id)
}| 字段 | 说明 | 默认 |
|---|---|---|
time | 窗口秒数 | 2 |
count | 窗口内最大次数 | 1 |
key | Redis key 前缀 | rateLimiter: |
type | DEFAULT 全局 / IP 按客户端 IP | DEFAULT |
算法:Redis Lua INCR,首次设置 EXPIRE;超过 count 抛 GuardError,文案为「访问过于频繁,请稍后重试」。
函数式:
ts
Application.POST(path, handler, {
rateLimit: { count: 3, time: 5 },
})@RepeatSubmit
ts
@PostController('/create')
@RepeatSubmit()
@Log({ title: '创建角色', business: BusinessType.CREATE })
create(@RequestBody() body: CreateRoleDTO) {
return this.roleService.createRole(body)
}| 字段 | 说明 | 默认 |
|---|---|---|
interval | 间隔毫秒 | 3000 |
message | 提示文案 | 请勿重复提交 |
规则:同一 URI + 登录用户(未登录用 anonymous)下,若请求体(或 query)相同且落在 interval 内,则拒绝。
函数式:repeatSubmit: {} 或带自定义 interval / message。
依赖与注意
- 必须可用 Redis(与 Auth 会话存储无关,走
src/core/Redis) - 多实例部署时限流 / 防重天然共享
- 失败统一
ResponseData,业务码一般为500