feat(auth): 添加 Refresh Token 双 Token 机制

- 添加 /api/refresh-token 接口支持 Token 续期
- 登录接口返回 access_token 和 refresh_token
- 新增 refresh_tokens 表存储 refresh_token
- 部署脚本添加数据库备份和迁移功能
- deploy.sh 添加 4 项 API 测试
- 更新 AGENTS.md 文档
This commit is contained in:
2026-04-19 16:01:41 +08:00
parent 52991dcfd5
commit e14c85436b
11 changed files with 872 additions and 98 deletions

View File

@@ -46,13 +46,53 @@ config/
migrations/ # 数据库迁移 SQL
tests/ # 集成测试
static/ # 静态文件KaTeX 等)
static/ # 静态文件
│ ├── css/
│ │ ├── report.css # PDF 报表样式
│ │ └── style.css # 通用样式
│ ├── js/
│ │ ├── afterbody.js # PDF 生成模块html2pdf
│ │ └── ...
│ └── katex/ # KaTeX 数学公式
deploy.sh # 部署脚本
.env.example # 环境变量模板
```
---
## PDF 报表生成
### 功能位置
`static/js/afterbody.js` - 使用 `html2pdf` 库生成 PDF 报表
### 依赖
- `html2pdf` - HTML 转 PDF 库
- `jspdf` - PDF 生成库
- `html2canvas` - HTML 转图片库
### 静态文件依赖
| 文件 | 用途 |
|------|------|
| `/static/css/style.css` | PDF 报表样式 |
| `/static/js/afterbody.js` | PDF 生成逻辑 |
### 生成流程
1. 前端调用后端获取天气数据
2. 后端返回 `weatherData` JSON
3. 前端加载 `afterbody.js`,将数据注入 `window.weatherData`
4. `afterbody.js` 构建 HTML 并调用 `html2pdf` 生成 PDF
### 注意事项
- ⚠️ 生成 PDF 前需确保 `/static/css/report.css` 存在
- 建议在 PDF 生成前检测静态文件可用性
---
## 配置管理
### 配置文件方式(推荐)
@@ -123,14 +163,35 @@ user_id INTEGER外键关联 users 表)
-- 30+ 个天气测量字段列
```
#### refresh_tokens 表
```sql
id SERIAL PRIMARY KEY
user_id INTEGER users
token VARCHARRefresh Token
expires_at TIMESTAMPTZ
created_at TIMESTAMPTZ
```
---
## 认证流程
1. **登录**`POST /api/login` 传入微信 code → 调用微信 API → UPSERT 用户 → 返回 JWT
2. **JWT 声明**`{exp, iat, user_id, openid, user_type}`24 小时过期)
3. **中间件**`jwt_middleware` 提取 Bearer 令牌,验证后将 Claims 插入请求扩展
4. **处理器访问**:通过 `claims: web::ReqData<Claims>` 参数获取
1. **登录**`POST /api/login` 传入微信 code → 调用微信 API → UPSERT 用户 → 返回双 Token
2. **双 Token 机制**
- `token`: access_token24小时用于 API 认证
- `refresh_token`: 7天有效期用于续期 access_token
3. **JWT 声明**`{exp, iat, user_id, openid, user_type}`
4. **中间件**`jwt_middleware` 提取 Bearer 令牌,验证后将 Claims 插入请求扩展
5. **处理器访问**:通过 `claims: web::ReqData<Claims>` 参数获取
6. **Token 刷新**`POST /api/refresh-token` 用 refresh_token 换取新的 access_token 和 refresh_token
### 公开接口
| 接口 | 说明 |
|------|------|
| `POST /api/login` | 微信登录,返回双 Token |
| `POST /api/refresh-token` | 刷新 access_token |
---
@@ -359,11 +420,28 @@ let new_expires = base_time + days(pkg_days);
./deploy.sh production --backup-list # 列出可用备份
```
**deploy.sh 功能**:依赖检查 → 编译 → 备份旧版本 → 上传二进制/配置 → 重启服务 → 部署后测试 → 记录日志 → Webhook 通知
**deploy.sh 功能**:依赖检查 → 编译 → 备份旧版本 → 清理旧备份保留5个 上传二进制/配置/迁移/脚本 → 重启服务 → **数据库备份****执行迁移** 部署后测试 → 记录日志 → Webhook 通知
**二进制备份**:自动保留最近 5 个备份,超出数量的旧备份在每次部署时自动清理。
**数据库备份**
- 位置:`${REMOTE_DIR}/backups/${DB_NAME}_*.dump`
- 保留数量1个
- 格式:`pg_dump -Fc`(自定义格式,可压缩)
**数据库迁移**
- 位置:`${REMOTE_DIR}/migrations/*.sql`
- 自动检测:检查表是否存在,跳过已执行的迁移
- 迁移文件名格式:`{序号}_{描述}.sql`
**自动回滚**:部署后测试失败时,自动回滚到上一个正常版本并重启服务。
- 回滚标记保存在 `${REMOTE_DIR}/.last_deployed`
- 测试失败后自动执行,无需手动干预
- Webhook 通知会发送失败回滚消息
**回滚:**
```bash
./deploy.sh production --rollback # 回滚生产环境
./deploy.sh production --rollback # 回滚生产环境(仅二进制)
```
**Webhook 通知(可选):**
@@ -385,6 +463,7 @@ WEBHOOK_URL="https://example.com/webhook" ./deploy.sh production
**deploy.sh 已包含的安全保障:**
- ✅ 部署前自动备份旧版本
- ✅ 部署前自动备份数据库
- ✅ 自动检查依赖
- ✅ 自动测试
- ✅ 部署日志记录