esbuker/elysia-nazli
GitHub: esbuker/elysia-nazli
为运行在 Bun 上的 Elysia 应用提供轻量级、可精细化配置的速率限制插件。
Stars: 1 | Forks: 0
# elysia-nazli
[](https://github.com/esbuker/elysia-nazli/actions/workflows/ci.yml)
[](https://github.com/esbuker/elysia-nazli/blob/master/.github/bundle-size.json)
为运行在 [Bun](https://bun.sh) 上的 [Elysia](https://elysiajs.com) 应用提供的轻量级、优雅的速率限制。
`elysia-nazli` 的入门非常简单:添加一个限制,保护你的路由,然后继续开发。当你的 API 需要更精细的控制时,它可以通过路由规则、组合 key、共享存储和更平滑的算法与你一起成长。
专为单个全局限制无法满足需求的实际服务而构建。
## 目录
- [为什么使用它](#why-use-it)
- [功能](#features)
- [快速开始](#quick-start)
- [安装说明](#installation)
- [使用示例](#usage-examples)
- [兼容性](#compatibility)
- [文档](#documentation)
- [开发](#development)
- [贡献](#contributing)
## 为什么使用它
当你的 Elysia 应用需要配置清晰且对真实流量足够严格的速率限制时,请使用 `elysia-nazli`:
- 只需几行代码即可设置一个全局限制作为起点。
- 为登录、注册、webhook 或昂贵的 endpoint 添加更严格的限制。
- 选择如何识别客户端:IP、用户 id、header、自定义逻辑或组合 key。
- 将状态保存在内存、SQLite、Redis 或你自己的 store 中。
- 决定当后端 store 缓慢或不可用时 API 的行为方式。
## 功能
- **全局、前缀和路由规则**,支持字符串或 `RegExp` 路径
- **Elysia 路由选项**支持 `{ rateLimit: { ... } }`
- **人类可读的时长字符串**,例如 `'30s'`、`'15m'`、`'2h'`,以及数字毫秒
- **感知 method 的限制**,适用于路由和前缀规则
- **算法:** fixed-window、sliding-window、token-bucket 和 GCRA
- **Key 解析器:** `ip`、`user`、`header`、`bodyField`、`firstOf`、`compose`、`hmac` 和 `custom`
- **Ban 窗口**,用于更严格的滥用处理
- **标准与 legacy headers**,支持按规则覆盖
- **存储:** 内存、SQLite、Redis 和自定义 `RateLimitStore` 实现
- **生产环境控制:** 按路由设置 store、fallback store、store 超时和失败策略
## 快速开始
安装该包:
```
bun add elysia-nazli
```
添加一个全局 limiter:
```
import { Elysia } from 'elysia'
import { rateLimit } from 'elysia-nazli'
const app = new Elysia()
.use(
rateLimit({
limit: 120,
window: '1m',
}),
)
.get('/', () => 'ok')
.listen(3000)
```
这允许每个客户端 key 每分钟 120 次请求。默认算法是 `fixed-window`,默认 store 是内存,并且启用了标准的 `ratelimit-*` headers。
## 安装说明
```
bun add elysia-nazli
```
Peer dependency:
```
bun add elysia
```
Redis 和 SQLite 辅助工具可通过 subpath exports 获取:
```
import { redisStore } from 'elysia-nazli/redis'
import { sqliteStore } from 'elysia-nazli/sqlite'
```
## 使用示例
### 全局加登录保护
```
import { Elysia } from 'elysia'
import { rateLimit } from 'elysia-nazli'
const app = new Elysia()
.use(
rateLimit({
namespace: 'my-api',
limit: 120,
window: '1m',
routes: {
'POST /login': {
limit: 10,
window: '15m',
ban: '5m',
},
},
}),
)
.post('/login', () => 'ok')
```
`/login` 路由必须同时通过全局规则和路由规则。
### 将限制保持在路由旁边
```
import { Elysia } from 'elysia'
import { rateLimit } from 'elysia-nazli'
const app = new Elysia()
.use(rateLimit())
.post('/login', () => 'ok', {
rateLimit: {
limit: 10,
window: '15m',
ban: '5m',
},
})
```
当关注局部可读性时使用路由选项。当你需要早期的 `onRequest` 限制、对象映射、`RegExp` 路径,或者需要一起评估多个匹配的规则时,请使用插件级别的 `routes`。
### 使用 Redis 和特定于规则的 key
```
import { RedisClient } from 'bun'
import { Elysia } from 'elysia'
import { bodyField, firstOf, ip, rateLimit, user } from 'elysia-nazli'
import { redisStore } from 'elysia-nazli/redis'
const redis = new RedisClient('redis://localhost:6379')
const app = new Elysia().use(
rateLimit({
algorithm: 'gcra',
key: firstOf(user('id'), ip({ trustedProxyDepth: 1 })),
store: redisStore({ client: redis, adapter: 'bun', prefix: 'myapp' }),
limit: 120,
window: '1m',
headers: {
standard: true,
legacy: false,
},
routes: {
'POST /login': {
limit: 10,
window: '15m',
ban: '5m',
key: bodyField('email', {
normalize: 'email',
hmacSecret: Bun.env.RATE_LIMIT_KEY_SECRET!,
}),
},
},
}),
)
```
### 为每个路由使用不同的 store
```
import { memoryStore, rateLimit } from 'elysia-nazli'
import { sqliteStore } from 'elysia-nazli/sqlite'
rateLimit({
store: memoryStore(),
limit: 120,
window: '1m',
routes: {
'POST /login': {
limit: 10,
window: '15m',
store: sqliteStore('./limits.sqlite'),
},
},
})
```
## 兼容性
- **Runtime:** Bun `>=1.3.13`
- **框架:** Elysia `^1.4.0`
- **Node.js:** 不是受支持的 runtime 目标
该包是 Bun 优先的。默认导入保持轻量,而 Redis 和 SQLite 辅助工具则位于 `elysia-nazli/redis` 和 `elysia-nazli/sqlite` 之后。
## 文档
| 指南 | 用途 |
| -------------------------------------------------- | ----------------------------------------------------------- |
| [文档索引](./docs/README.md) | 快速找到合适的指南 |
| [示例与模式](./docs/examples.md) | 常见设置、登录保护、代理安全 IP |
| [配置参考](./docs/configuration.md) | 选项、默认值、验证、headers、路由宏 |
| [Store 与后端](./docs/stores.md) | 内存、SQLite、Redis、自定义 store |
| [算法与语义](./docs/algorithm.md) | 算法权衡、规则匹配、ban、成本 |
| [生产与弹性](./docs/production.md) | 失败策略、fallback store、超时、代理、扩展 |
## 开发
```
bun install
bun run typecheck
bun run test
bun run build
```
实用脚本:
| 命令 | 作用 |
| -------------------------- | ----------------------------------------------- |
| `bun run test` | 运行测试套件 |
| `bun run test:integration` | 运行集成测试 |
| `bun run typecheck` | 检查 TypeScript 但不生成文件 |
| `bun run lint` | 运行 ESLint |
| `bun run format:check` | 检查 Prettier 格式 |
| `bun run build` | 构建 JS、声明和 bundle size 报告 |
| `bun run bench` | 运行本地基准测试 |
| `bun run bench:compare` | 比较 Elysia 插件请求路径吞吐量 |
| `bun run release:check` | 运行类型检查、测试和构建 |
## 贡献
欢迎提交关于 bug、安全复现案例和聚焦的功能讨论的 Issue。目前不接受外部 pull request。
在打开 issue 之前,请参阅 [CONTRIBUTING.md](./CONTRIBUTING.md) 和 [SECURITY.md](./SECURITY.md)。
## 许可证
[MIT](./LICENSE)
标签:API保护, Bun, Elysia, Syscall, Web开发, 中间件, 搜索引擎查询, 自动化攻击, 限流