【立项背景和目标】
中小团队做内部管理系统时,登录鉴权、角色权限、用户管理这些基础模块几乎每个项目都要重写一遍,既浪费时间,权限校验也容易写漏,留下越权漏洞。本项目目标是把这套通用底座做成可直接复用的脚手架:后端提供接口级强制权限校验,前端提供可复用的管理界面,新项目接入后只需专注业务模块,不必重复造轮子。
【核心功能模块】
1. 认证模块:JWT 令牌登录,密码使用 PBKDF2-HMAC-SHA256 加盐哈希(12 万次迭代),接口响应永不返回密码等敏感字段。
2. 权限模块(RBAC):用户—角色—权限点三级模型,内置超级管理员、运营人员、只读访客三个角色,权限在后端强制拦截。
3. 用户管理模块:关键词模糊搜索,角色/状态/部门多条件筛选,分页(每页 10/20/50 可调),增删改查,启用禁用,重置密码,CSV 导出(带 UTF-8 BOM,Excel 打开中文不乱码)。
4. 数据看板模块:统计卡片、近 30 天注册趋势折线图、角色分布环形图、最近操作记录列表。
5. 审计模块:记录登录、登出、登录失败、增删改、导出等全部写操作,含操作人、IP、时间。
【业务流程和功能路径】
用户登录 → 后端校验账号密码并签发 JWT → 前端携带令牌请求接口 → 后端解析令牌、查库校验账号是否被禁用、再校验当前角色是否具备该接口所需权限点 → 通过则返回数据,否则返回 401 或 403 → 前端依据返回的权限列表决定展示哪些菜单与按钮 → 所有写操作同步写入审计日志 → 看板实时汇总统计。
【整体架构和设计思路】
前后端分离的单体架构。后端 Python + FastAPI,分「路由层 / 依赖注入层 / 数据访问层」三层:routers 只声明需要什么权限,deps.py 用 Depends 把「解析令牌→查库→校验状态→校验权限点」串成可复用依赖,database.py 封装全部 SQL。数据库用 SQLite 做到零依赖、克隆即跑,迁移 PostgreSQL 只需替换数据访问层。密码哈希用标准库 hashlib 实现,避开 bcrypt 等需编译的库。前端 Vue 3 + Element Plus + ECharts,第三方库全部本地化到 vendor 目录,断网也能演示。部署用 Docker 单镜像同时提供 API 与前端页面,前后端同源,无需配置跨域。
【我负责的模块和结果】
独立完成架构设计、接口开发、前端实现到容器化部署全流程。可量化结果:
- 后端 10 个模块、1241 行 Python,14 个 REST 接口,3 个角色 6 个权限点;
- 前端 592 行 JS + 393 行 HTML + 192 行 CSS,4 个功能页面;
- 自研 36 例接口自动化测试(不用第三方测试框架,仅标准库 urllib),覆盖认证、权限拦截反向用例、CRUD 全生命周期、参数边界、CSV 编码校验,全部通过;
- 自研无头浏览器端到端脚本,40 项断言全通过,运行时 JS 报错 0 条,并自动产出 9 张界面截图;
- 接口响应注入 X-Request-ID 与 X-Process-Time 便于排障,列表接口平均响应约 8ms。
【遇到的难点、坑和解决方案】
1. 浏览器内 DOM 模板的自闭合标签陷阱。前端免构建、模板直接写在 HTML 里,而 HTML 解析器不认识 这类自定义标签,自闭合写法不生效,后续兄弟节点会被当成插槽内容吞掉,现象是「工具栏按钮凭空消失」且控制台没有明显报错,排查耗时较久。改为成对闭合标签解决,并加了静态检查防止复发。
2. ECharts 在隐藏容器上 resize 抛异常。v-show 隐藏面板时容器宽高为 0,此时窗口 resize 触发 chart.resize(),ECharts 重算布局会抛 TypeError。改为 resize 前先判断容器可见且有真实尺寸,并加 150ms 防抖;另外 v-if/v-else 切换会销毁重建 DOM,图表实例必须同步 dispose(),否则会操作已脱离文档的容器。
3. 权限校验该放在哪一层。最初靠前端隐藏按钮控制,实测用 Postman 直接调接口依然能越权。改为后端接口级强制校验、前端仅做展示层隐藏,并补充了「只读角色调用删除接口必须返回 403」的反向测试用例。