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 全绿;二进制端到端冒烟通过
3.8 KiB
3.8 KiB
认证与限流
角色
| 角色 | 能力 |
|---|---|
| 游客(无 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)。 - 密码存储为 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:
{ "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 下发,客户端不应自行构造。
示例
登录获取令牌:
curl -s http://localhost:8466/admin/login \
-H 'Content-Type: application/json' \
-d '{"password":"your-admin-password"}'
{
"code": 200, "msg": "ok",
"data": {
"id": "admin", "username": "admin",
"token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_at": 1750000000,
"expires_in": 604800
}
}
携带令牌调用管理接口:
TOKEN="eyJhbGciOiJIUzI1NiIs..."
curl -s http://localhost:8466/admin/dashboard -H "Authorization: Bearer $TOKEN"
校验令牌是否有效:
curl -s http://localhost:8466/admin/verify -H "Authorization: Bearer $TOKEN"
{
"code": 200, "msg": "ok",
"data": { "id": "admin", "username": "admin", "token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "Bearer", "expires_at": 1750000000 }
}
令牌失效时:
{ "code": 401, "msg": "令牌无效或已过期" }