- 数据库默认文件 filecodebox.db → fileshare.db(config.go 默认值与全部文档/编排同步)
- Go module filecodebox → fileshare(全部 import 同步,build/vet/test 全绿)
- 应用版本 APP_VERSION 2.5.6 → 26.9(health 接口已验证返回 26.9)
- deploy 编排统一:compose 项目名、Postgres 默认凭据、minio 桶名、env 注释
- JWT issuer、存储临时目录前缀、web 包名同步 fileshare
- CI:镜像 tag 以 APP_VERSION 为唯一版本源,main/tag 推送即发布
${VER} + latest;tag 触发时校验 tag 名与 APP_VERSION 一致,防错版
- 本地开发库文件已改名 fileshare.db(含 -shm/-wal 清理)
106 lines
3.7 KiB
Markdown
106 lines
3.7 KiB
Markdown
# 认证与限流
|
||
|
||
## 角色
|
||
|
||
| 角色 | 能力 |
|
||
|---|---|
|
||
| 游客(无 Authorization 头) | 取件、查询元信息;`openUpload=1` 时可上传 |
|
||
| 管理员(`Authorization: Bearer <JWT>`) | 全部能力 + `/admin/*` 管理接口 |
|
||
|
||
## 管理员令牌
|
||
|
||
- 由 `POST /admin/login` 用管理员密码换取,HS256 JWT,默认有效期 **7 天**(`adminSessionExpire`,1~365 整天,26.9 起由 30 天缩短)。
|
||
- 请求头格式:`Authorization: Bearer <token>`。
|
||
- **改密/重置管理员密码会轮换 `jwt_secret`,所有已签发令牌立即失效**(401)。
|
||
- 密码存储为 bcrypt(cost 12);历史 `sha256$`/明文格式在登录成功后自动升级重哈希,无需手动迁移。
|
||
- 游客上传关闭(`openUpload=0`)时,上传类接口也可用管理员 Bearer 令牌通过鉴权。
|
||
|
||
## 认证失败语义
|
||
|
||
| 场景 | 状态码 |
|
||
|---|---|
|
||
| `/admin/*` 缺失/无效令牌 | 401 |
|
||
| `POST /admin/login` 密码错误 | 401(并计入 login 限流) |
|
||
| 游客上传被关闭且未携带有效令牌 | 403 |
|
||
| 代理下载 `key` 校验失败 | 403 |
|
||
|
||
## 未初始化(428)
|
||
|
||
管理员密码未设置(`admin_token` 为空)时,除 `GET|POST /setup` 与 `GET /api/v1/health` 外全部接口返回 428。
|
||
完成 `POST /setup` 初始化后自动解除。
|
||
|
||
## 限流规则
|
||
|
||
限流按 **客户端 IP** 维度(配置 `FCB_TRUSTED_PROXIES` 声明可信代理 CIDR,命中时解析 `X-Forwarded-For` 取真实 IP),
|
||
窗口计数原子化存储于缓存(未配置 Redis 时为进程内存)。**超限一律返回 423**:
|
||
|
||
```json
|
||
{ "code": 423, "msg": "请求次数过多,请稍后再试" }
|
||
```
|
||
|
||
| 规则 | 生效端点 | 计数时机 | 默认 | 配置键 |
|
||
|---|---|---|---|---|
|
||
| `upload` | `/share/text`、`/share/file`、`/chunk/upload/*`、`/presign/upload/*` | **成功后**计数(进入时仅检查) | 10 次 / 1 分钟 | `uploadCount`、`uploadMinute` |
|
||
| `error` | `/share/select`、`/share/download` | 取件失败(不存在/过期/鉴权失败)时计数 | 10 次 / 1 分钟 | `errorCount`、`errorMinute` |
|
||
| `login` | `/admin/login` | 登录失败时计数 | 5 次 / 15 分钟 | `loginCount`、`loginMinute` |
|
||
| `metadata` | `/share/metadata` | **每次访问即计数**(含失败) | 同 `error` | `errorCount`、`errorMinute` |
|
||
|
||
- 规则值可由管理端 `PATCH /admin/config/update` 运行时修改,立即生效(无需重启)。
|
||
- 取件成功(`/share/select`、`/share/download`)不计入 `error` 限流。
|
||
|
||
## 代理下载令牌(key)
|
||
|
||
`GET /share/download` 的 `key` 由服务端按窗口生成:
|
||
`sha256(code + timeFactor + "000" + jwt_secret)`,`timeFactor = unix秒 / 1000`(约 16.7 分钟一个窗口)。
|
||
服务端**同时接受当前与上一窗口**的令牌,避免窗口边界竞态。令牌通过 `POST /share/select` 的响应
|
||
`download_url` 下发,客户端不应自行构造。
|
||
|
||
## 示例
|
||
|
||
登录获取令牌:
|
||
|
||
```bash
|
||
curl -s http://localhost:8466/admin/login \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"password":"your-admin-password"}'
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"id": "admin", "username": "admin",
|
||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||
"token_type": "Bearer",
|
||
"expires_at": 1750000000,
|
||
"expires_in": 604800
|
||
}
|
||
}
|
||
```
|
||
|
||
携带令牌调用管理接口:
|
||
|
||
```bash
|
||
TOKEN="eyJhbGciOiJIUzI1NiIs..."
|
||
curl -s http://localhost:8466/admin/dashboard -H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
校验令牌是否有效:
|
||
|
||
```bash
|
||
curl -s http://localhost:8466/admin/verify -H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": { "id": "admin", "username": "admin", "token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "Bearer", "expires_at": 1750000000 }
|
||
}
|
||
```
|
||
|
||
令牌失效时:
|
||
|
||
```json
|
||
{ "code": 401, "msg": "令牌无效或已过期" }
|
||
```
|