feat: 新增 /admin 只读授权管理后台
- admin.py:HTTP Basic Auth + 服务端渲染单页,概览统计 / 用户与当前授权 / 最近使用记录 / 会话令牌 / 扫码场景五个区块 - ADMIN_PASSWORD 为空时返回 503 而非放行,避免漏配密码导致全库数据公开 - 不引模板引擎与 CDN,所有入库文本经 html.escape;令牌只显示首尾便于比对 - config.py / .env.example 新增 ADMIN_USER / ADMIN_PASSWORD - wechat.py 挂载 admin.router;CODEBUDDY.md 补充文档
This commit is contained in:
1 parent
3a8adda365
commit
f167550957
5 files changed
+410
-3
No files matched your search
+14
-2
@@ -4,7 +4,7 @@ This file provides guidance to CodeBuddy Code when working with code in this rep
|
||||
|
||||
## 项目概述
|
||||
|
||||
微信公众号扫码授权服务,基于 FastAPI,为 Windows MFC 桌面程序提供微信扫码授权与使用扣减。已实现微信服务器验证与消息/事件接收(`/wechat`)、扫码授权(`/auth`)、使用扣减(`/usage`)以及首次关注赠送 7 天免费授权。MySQL 已接入(aiomysql 连接池,5 张表);Redis 仅在配置层声明,尚未使用。
|
||||
微信公众号扫码授权服务,基于 FastAPI,为 Windows MFC 桌面程序提供微信扫码授权与使用扣减。已实现微信服务器验证与消息/事件接收(`/wechat`)、扫码授权(`/auth`)、使用扣减(`/usage`)、只读管理后台(`/admin`)以及首次关注赠送 7 天免费授权。MySQL 已接入(aiomysql 连接池,5 张表);Redis 仅在配置层声明,尚未使用。
|
||||
|
||||
## 常用命令
|
||||
|
||||
@@ -38,6 +38,7 @@ wechat_api.py # 微信开放接口:access_token 内存缓存 + 临时二维
|
||||
wechat.py # FastAPI app 本体:lifespan + /wechat 路由 + 签名校验 + XML 解析/构造
|
||||
auth.py # /auth/* 路由 + 扫码授权业务逻辑(含 pending 激活)
|
||||
usage.py # /usage/consume 路由:会话校验与使用扣减
|
||||
admin.py # /admin 只读管理后台:Basic Auth + 服务端渲染 HTML
|
||||
run_local.py # 开发启动入口(reload=True)
|
||||
run_server.py # 生产启动入口(reload=False, workers=1)
|
||||
sql/schema.sql # 建表脚本(5 张表,含索引与外键)
|
||||
@@ -45,7 +46,7 @@ sql/schema.sql # 建表脚本(5 张表,含索引与外键)
|
||||
|
||||
- **配置**:所有敏感值经 `config.py` 从 `.env` 读取,`.env` 已被 `.gitignore` 排除。`.env.example` 是字段模板。新增配置项需同时更新这两处。
|
||||
- **应用入口**:两个启动脚本均以 `"wechat:app"` 字符串形式加载 `wechat.py` 中的 `app`,因此模块名/对象名不可随意重命名。`lifespan` 在启动时初始化 MySQL 连接池——**MySQL 不可达或库表不存在时应用会直接启动失败**。
|
||||
- **路由挂载**:`wechat.py` 通过 `include_router` 挂载 `auth.router` 与 `usage.router`。新增 MFC 侧接口应新建独立模块的 router,而不是塞进 `wechat.py`。
|
||||
- **路由挂载**:`wechat.py` 通过 `include_router` 挂载 `auth.router`、`usage.router` 与 `admin.router`。新增 MFC 侧接口应新建独立模块的 router,而不是塞进 `wechat.py`。
|
||||
- **微信交互协议**:
|
||||
- 所有请求先经 `verify_signature()`(token+timestamp+nonce 字典序拼接后 SHA1 比对)校验,失败返回 403。
|
||||
- GET 校验通过后原样返回 `echostr`。
|
||||
@@ -63,6 +64,17 @@ sql/schema.sql # 建表脚本(5 张表,含索引与外键)
|
||||
- **usage_logs**:积分授权每次调用都写(计费凭证);时间授权按 `(user_id, device_id)` 在 `USAGE_LOG_THROTTLE_SECONDS`(默认 60 秒)窗口内节流。
|
||||
- **失败语义**:`/usage/consume` 一律返回 HTTP 200,用 `{"ok": false, "reason": "expired | exhausted | invalid_token"}` 表达失败。
|
||||
|
||||
## 管理后台(/admin)
|
||||
|
||||
只读单页,用于查看用户与授权现状:概览统计、用户+当前授权、最近使用记录、会话令牌、扫码场景。
|
||||
|
||||
- **鉴权**:HTTP Basic Auth,凭据取自 `.env` 的 `ADMIN_USER` / `ADMIN_PASSWORD`,用 `secrets.compare_digest` 做定时安全比较。
|
||||
- **`ADMIN_PASSWORD` 为空时 `/admin` 返回 503 而非放行**——不要把它当成可选项,否则等于把全库用户数据公开。
|
||||
- **只提供 GET**,没有任何写操作(改授权/加积分/封号一律不做)。
|
||||
- **不引模板引擎**:HTML 由 f-string 拼装,所有入库字段经 `html.escape()`;CSS 内联,不依赖任何 CDN(服务器出网不可靠)。
|
||||
- 页脚会显示数据库名;页头显示数据生成时间。不做自动刷新。
|
||||
- `admin.py` 被 `wechat.py` import,因此**不要在 `admin.py` 里反向 import `wechat`**(循环依赖)。
|
||||
|
||||
## 数据库
|
||||
|
||||
5 张表(定义见 `sql/schema.sql`):`users`、`authorizations`(授权,type 分 time/points)、`auth_scenes`(扫码场景,300 秒一次性)、`usage_logs`(使用日志)、`sessions`(会话令牌)。
|
||||
|
||||
Reference in new issue
Block a user