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:
93
AGENTS.md
93
AGENTS.md
@@ -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 VARCHAR(Refresh 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_token(24小时),用于 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 已包含的安全保障:**
|
||||
- ✅ 部署前自动备份旧版本
|
||||
- ✅ 部署前自动备份数据库
|
||||
- ✅ 自动检查依赖
|
||||
- ✅ 自动测试
|
||||
- ✅ 部署日志记录
|
||||
|
||||
Reference in New Issue
Block a user