Skip to content

限流与防重复提交

实现位于 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
keyRedis key 前缀rateLimiter:
typeDEFAULT 全局 / IP 按客户端 IPDEFAULT

算法:Redis Lua INCR,首次设置 EXPIRE;超过 countGuardError,文案为「访问过于频繁,请稍后重试」。

函数式:

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

相关章节

基于 VitePress 构建