Files
FileShare/docs/api/01-auth.md
T
SKYMirror 9686fe887a FileCodeBox Go 重写版 v2.5.6(安全审计修复版)
Go 1.27.1 (Gin+GORM) + Vue 3 文件快传服务:

- 安全审计全部修复(docs/security-audit-2026-09-05.md):
  bcrypt 密码哈希与自动升级、presign 直传服务端大小/内容校验、
  全局请求体上限、依赖升级(govulncheck 0 命中)、janitor 后台清理、
  管理端审计动作落库、/admin CORS 收紧、通知内容白名单净化、
  会话默认 7 天、限流缓存故障降级、robots.txt 端点等
- 前端:取件链接复制修复(不再重复拼接提取码)、markdown 净化器加固
- Redis 支持库号(FCB_REDIS_DB / redis://…/db URL)
- 文档:docs/api/* 与 openapi.yaml 同步最新行为(robots.txt、
  提码 5 位起、chunk 32MiB 上限、admin 审计动作等)

验证:gofmt/go vet/go test 全绿;二进制端到端冒烟通过
2026-09-05 04:22:41 +08:00

106 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 认证与限流
## 角色
| 角色 | 能力 |
|---|---|
| 游客(无 Authorization 头) | 取件、查询元信息;`openUpload=1` 时可上传 |
| 管理员(`Authorization: Bearer <JWT>` | 全部能力 + `/admin/*` 管理接口 |
## 管理员令牌
-`POST /admin/login` 用管理员密码换取,HS256 JWT,默认有效期 **7 天**`adminSessionExpire`1~365 整天,v2.5.6 起由 30 天缩短)。
- 请求头格式:`Authorization: Bearer <token>`
- **改密/重置管理员密码会轮换 `jwt_secret`,所有已签发令牌立即失效**(401)。
- 密码存储为 bcryptcost 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": "令牌无效或已过期" }
```