Flask Session -> Double Token
This commit is contained in:
@@ -45,11 +45,17 @@
|
||||
↓
|
||||
访问 /control → 输入 6 位数字(自动识别 TOTP / 临时账户 TOTP / Root 临时密码)
|
||||
↓
|
||||
登录成功 → 签发 access token(前端持有)+ refresh token(httpOnly cookie)
|
||||
↓
|
||||
Root 临时密码 → 强制跳转 /mfa-setup 配置 MFA
|
||||
正式用户 TOTP/Passkey → 直接进入控制面板
|
||||
临时账户 TOTP → 强制跳转 /mfa-setup 配置登录方式,配置完成后临时 TOTP 立即失效
|
||||
```
|
||||
|
||||
**会话管理**:
|
||||
- 控制端「设置 → 踢掉当前账号的所有设备」:所有登录该账号的设备(控制端 + 显示端,含当前设备)立即下线,**所有登录用户可用**
|
||||
- Root「用户管理 → 踢掉所有用户」:所有用户的控制端与显示端全部下线(含 Root 自身),需二次验证
|
||||
|
||||
**用户管理(仅 Root)**:
|
||||
- 管理员代注册:填写信息 → 正式账户,可随后代配置 TOTP(生成密钥+二维码)或 Passkey(注册仪式在当前浏览器完成)
|
||||
- 用户自助申请:用户在 `/register-request` 填写信息 → 管理员确认 → 生成临时账户(服务器持有临时 TOTP 密钥,管理员仅看到实时验证码)
|
||||
@@ -61,8 +67,9 @@ Root 临时密码 → 强制跳转 /mfa-setup 配置 MFA
|
||||
- 登录频率限制(渐进式封禁:5次→5分钟、10次→15分钟、15次→24小时)
|
||||
- CSRF 防护(Origin/Referer 校验)
|
||||
- 敏感操作二次验证(用户管理、MFA 配置需重新确认身份)
|
||||
- 会话 Cookie HttpOnly + SameSite=Lax + Secure(HTTPS 下)
|
||||
- 会话版本按用户存储:删除用户 / "踢掉所有显示端" 立即失效
|
||||
- **双 Token 认证**:短期 access token(`Authorization: Bearer`,15 分钟)+ 长期 refresh token(httpOnly cookie,30 天滑动续期、每次刷新轮换)
|
||||
- Access token 快照会话版本:删除用户 / 踢设备 / 踢所有用户后**立即**使全部 access token 失效
|
||||
- 显示端 SSE 通过一次性短时 ticket 鉴权(EventSource 无法带自定义 header)
|
||||
- 内容安全策略(CSP)限制脚本/样式来源
|
||||
- 铃声上传仅允许音频格式+MIME 校验
|
||||
- 第三方日历数据 HTML 转义防止 XSS
|
||||
@@ -225,8 +232,8 @@ location / {
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `FLASK_HTTPS` | 空 | 设为 `yes`/`true` 启用 Secure Cookie(Nginx 反代时启用) |
|
||||
| `FLASK_SECRET_KEY` | 自动随机生成 | 固定密钥使会话跨重启保持有效 |
|
||||
| `FLASK_HTTPS` | 空 | 设为 `yes`/`true` 启用 refresh token cookie 的 Secure 属性(Nginx 反代时启用) |
|
||||
| `FLASK_SECRET_KEY` | 自动随机生成 | 保留兼容;认证已由 access/refresh 双 token 承载,不再依赖 Flask session |
|
||||
| `FLASK_BIND` | `127.0.0.1` | 监听地址,Docker 部署需设为 `0.0.0.0` |
|
||||
| `FLASK_DB_PATH` | `./data.db` | 数据库文件路径,Docker 挂载数据卷时需同步修改 |
|
||||
| `FLASK_DEBUG` | 空 | 设为 `true` 开启 Flask 调试模式(**生产环境禁用**) |
|
||||
@@ -241,26 +248,35 @@ location / {
|
||||
├── requirements.txt
|
||||
├── backend/
|
||||
│ ├── app.py # Flask 应用工厂 + 安全配置
|
||||
│ ├── auth.py # MFA 认证(TOTP/Passkey/恢复码/临时密码)
|
||||
│ ├── auth.py # 双 Token 认证(TOTP/Passkey/恢复码/临时密码)
|
||||
│ ├── webauthn_mgr.py # WebAuthn (Passkey) 注册与认证
|
||||
│ ├── jwt_util.py # Ed25519 JWT 签名(和风天气)
|
||||
│ ├── models.py # SQLite 数据库模型与迁移
|
||||
│ ├── routes.py # 全部 API 路由 + CSRF 防护
|
||||
│ ├── models.py # SQLite 模型、schema 版本迁移、token 管理
|
||||
│ ├── routes.py # 全部 API 路由 + CSRF 防护 + SSE ticket
|
||||
│ └── *_mgr.py # 各功能模块管理器
|
||||
└── frontend/
|
||||
├── templates/ # HTML 模板
|
||||
└── static/
|
||||
├── css/ # 样式
|
||||
├── js/ # JavaScript(纯原生,无框架)
|
||||
│ ├── token.js # 双 Token 客户端(access 存储/刷新/401 重试/SSE ticket)
|
||||
│ ├── control.js # 控制端逻辑
|
||||
│ └── display.js # 显示端逻辑(账户时区渲染)
|
||||
└── ringtones/ # 自定义铃声
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 数据库迁移(升级无需重写数据)
|
||||
### 数据库迁移(版本化,升级无需重写数据)
|
||||
|
||||
数据库内置 `meta` 表记录 **schema 版本**(程序内 `DB_VERSION`,当前为 1)。每次启动时比对:
|
||||
|
||||
| 情况 | 行为 |
|
||||
|------|------|
|
||||
| 数据库版本 == 程序版本 | 直接使用,跳过重建 |
|
||||
| 无版本字段(旧版数据库)或 数据库版本 < 程序版本 | 重建数据库并迁移(旧版单用户数据自动归属 Root (id=0),新增字段一律用 DEFAULT 填充,`camera_config` 等已删除的表自动丢弃) |
|
||||
| 数据库版本 > 程序版本 | **报错并终止启动**(数据库比程序新,需先升级程序) |
|
||||
|
||||
启动时会自动检测并迁移数据库:旧版单用户数据库的数据自动归属 Root (id=0);
|
||||
新增的字段一律带 DEFAULT 并在迁移时自动填充;`camera_config` 等已删除的表自动丢弃。
|
||||
旧版 4 位 PIN 不会被迁移。运行测试:`python3 tests/test_multi_user.py`。
|
||||
|
||||
## 注意
|
||||
|
||||
Reference in New Issue
Block a user