feat(BIZ-129): auth_api 蓝图 + 7 接口(login/logout/me/refresh/change-password/reset-request/reset-confirm)

- auth_api.py: Blueprint 独立文件,不污染 app.py 业务路由
- session 存 sha256 hash 入库(架构决策 #2,依赖 auth.py lookup_session)
- cookie HttpOnly + SameSite=Lax(Secure 留给部署层 nginx)
- 错误返回统一:{'success': False, 'error': str, 'code': str}
- 防用户名枚举:reset-request 即便用户不存在也返回 ok
- change-password 成功后强制吊销当前 session(防 session 复用)
- reset-confirm 成功后吊销该用户所有 session(防攻击者已登录状态)

依赖:auth.py + auth_db.py(commit ab9b62e)

BIZ-127 架构决策对齐:
  ✓ #1 bcrypt rounds=12(依赖 auth.py hash_password)
  ✓ #2 session token_hash = sha256(cookie_value)
  ✓ #5 5 次失败锁定 15 分钟(依赖 auth.py authenticate)
  ✓ #6 重置 token token_urlsafe(32) + 2h 过期 + 一次性(依赖 auth.py create_reset_token / consume_reset_token)
  ✓ #8 操作日志 90 天保留(依赖 auth.py write_op_log)

未完成(commit 2/3/4):
  - Flask-Limiter 集成(commit 2)
  - 前端 3 页(commit 3)
  - pytest 端到端(commit 4)

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
costcodev
2026-09-05 07:09:08 +08:00
parent ab9b62e9b3
commit b002e929dc
2 changed files with 376 additions and 0 deletions
+12
View File
@@ -31,6 +31,18 @@ from lottery import DoubleColorBallGenerator
app = Flask(__name__)
# ============================================================
# 认证 API 蓝图注册(BIZ-129 方案 C)
# ============================================================
# auth_api.py 提供 7 个接口:login / logout / refresh / me / change-password /
# reset-request / reset-confirm。session 存 sha256 hash 入库(架构决策 #2)。
try:
from auth_api import register_auth_api
register_auth_api(app)
except ImportError as e:
# auth_api.py 未就绪时不影响主流程(保持向后兼容)
print(f'[BIZ-129] auth_api 蓝图注册跳过:{e}', file=sys.stderr)
# ============================================================
# 中奖金额常量表(PRD v1.2 BIZ-105 §4.3)
# ============================================================