Files
2026-02-28 15:16:15 +08:00

15 KiB
Raw Permalink Blame History

权限控制机制

**本文引用的文件** - [backend/app/core/security.py](file://backend/app/core/security.py) - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py) - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py) - [backend/app/services/staff_service.py](file://backend/app/services/staff_service.py) - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py) - [backend/app/services/menu_service.py](file://backend/app/services/menu_service.py) - [backend/app/core/config.py](file://backend/app/core/config.py) - [backend/app/main.py](file://backend/app/main.py) - [backend/app/core/logging_config.py](file://backend/app/core/logging_config.py) - [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件系统化阐述医院绩效系统的权限控制机制重点覆盖基于角色的访问控制RBAC实现、菜单权限与数据权限设计、JWT令牌验证、用户角色分配与权限继承机制。文档同时给出不同角色管理员、科室负责人、普通员工的权限范围与操作限制解释后端中间件式权限校验、动态权限检查与安全审计日志策略并提供权限配置的扩展方式、权限矩阵与安全最佳实践。

项目结构

后端采用 FastAPI + SQLAlchemy 异步 ORM 的分层架构,权限控制相关代码主要集中在以下模块:

  • 安全与认证core/security.py、api/v1/auth.py、core/config.py
  • 数据模型models/models.py含用户、菜单等
  • 前端路由守卫frontend/src/router/index.js令牌拦截
  • 日志与审计core/logging_config.py
  • API 路由聚合api/v1/init.py
graph TB
subgraph "后端"
A["main.py<br/>应用入口与CORS"]
B["api/v1/__init__.py<br/>路由聚合"]
C["core/security.py<br/>JWT与权限依赖"]
D["api/v1/auth.py<br/>登录/注册/当前用户"]
E["models/models.py<br/>User/Menu等模型"]
F["core/config.py<br/>JWT配置"]
G["core/logging_config.py<br/>日志与审计"]
end
subgraph "前端"
H["frontend/src/router/index.js<br/>路由守卫"]
end
H --> A
A --> B
B --> D
D --> C
C --> E
C --> F
A --> G

图表来源

章节来源

核心组件

  • JWT 与令牌管理:负责令牌签发、解码、过期控制与用户解析。
  • 权限依赖注入:提供“当前用户”、“当前有效用户”、“管理员”、“管理员或经理”的依赖函数,作为路由装饰器实现中间件式权限控制。
  • 用户模型与角色User 模型包含 role 字段,支持 admin、manager、staff 角色。
  • 菜单模型与权限标识Menu 模型包含 permission 字段,用于前端按钮级权限标识。
  • 员工与菜单 API通过依赖注入实现不同角色的访问控制。

章节来源

架构总览

后端通过 FastAPI 的依赖注入系统,在每个路由上声明所需的权限依赖,实现“中间件式”的权限控制。前端通过路由守卫拦截未登录访问,后端通过 OAuth2 Bearer 令牌进行鉴权。

sequenceDiagram
participant FE as "前端"
participant API as "FastAPI路由"
participant SEC as "security依赖"
participant DB as "数据库"
participant MOD as "模型(User)"
FE->>API : "携带Authorization : Bearer token"
API->>SEC : "依赖注入 : get_current_user()"
SEC->>SEC : "decode_token()"
SEC->>DB : "按ID查询用户"
DB-->>SEC : "返回User"
SEC->>MOD : "校验is_active"
MOD-->>API : "返回当前用户"
API-->>FE : "执行业务逻辑/返回数据"

图表来源

详细组件分析

JWT 与令牌验证

  • 令牌签发:使用 HS256 算法,包含 exp 与 sub用户ID默认有效期 8 小时。
  • 令牌解码:验证签名与过期时间,失败则抛出凭据无效异常。
  • 用户解析:从载荷提取 sub用户ID查询数据库获取用户实体并校验 is_active。
  • 依赖链路OAuth2PasswordBearer 提供 tokenUrlget_current_user 解析用户get_current_active_user 进一步校验状态。
flowchart TD
Start(["进入受保护路由"]) --> GetToken["从Authorization头获取Bearer token"]
GetToken --> Decode["decode_token() 验证签名与过期"]
Decode --> Valid{"解码成功?"}
Valid --> |否| Raise401["抛出401未授权"]
Valid --> |是| LoadUser["按ID查询User"]
LoadUser --> Active{"is_active=true"}
Active --> |否| Raise403["抛出403禁止访问"]
Active --> |是| ReturnUser["返回当前用户"]
Raise401 --> End(["结束"])
Raise403 --> End
ReturnUser --> End

图表来源

章节来源

RBAC 角色与权限继承

  • 角色定义User.role 支持 admin管理员、manager经理、staff普通员工
  • 权限依赖:
    • get_current_active_user校验用户激活状态。
    • get_current_manager_user要求 admin 或 manager。
    • get_current_admin_user要求 admin。
  • 路由装饰示例:
    • 员工管理:创建/更新/删除需管理员或经理权限。
    • 菜单管理:创建/更新/删除需管理员或经理权限;初始化默认菜单需管理员权限。
classDiagram
class User {
+int id
+string username
+string role
+bool is_active
}
class SecurityDeps {
+get_current_user(token) User
+get_current_active_user(user) User
+get_current_manager_user(user) User
+get_current_admin_user(user) User
}
class StaffAPI {
+create_staff() Response
+update_staff() Response
+delete_staff() Response
}
class MenuAPI {
+create_menu() Response
+update_menu() Response
+delete_menu() Response
+init_default_menus() Response
}
StaffAPI --> SecurityDeps : "依赖manager/admin"
MenuAPI --> SecurityDeps : "依赖manager/admin"
SecurityDeps --> User : "返回当前用户"

图表来源

章节来源

菜单权限与前端集成

  • 菜单模型Menu 包含 permission 字段,用于前端按钮级权限标识。
  • 菜单服务:提供树形结构、列表查询、默认初始化等能力。
  • 前端路由守卫:未登录访问会被重定向至登录页,确保前端侧最小暴露面。
sequenceDiagram
participant FE as "前端"
participant API as "菜单API"
participant SVC as "MenuService"
participant DB as "数据库"
FE->>API : "GET /menus/tree?visible_only=true"
API->>SVC : "get_tree(visible_only)"
SVC->>DB : "查询可见且启用的菜单树"
DB-->>SVC : "返回菜单树"
SVC-->>API : "返回树形结构"
API-->>FE : "渲染菜单树/按钮权限"

图表来源

章节来源

数据权限与业务边界

  • 员工管理:仅管理员或经理可增删改;查询列表对所有有效用户开放。
  • 菜单管理:对菜单树与列表查询不强制管理员权限,但对写操作(创建/更新/删除/初始化)要求管理员或经理。
  • 建议扩展:可在服务层增加“数据域过滤”,例如按用户关联的 staff_id 或 department_id 限制查询范围,避免越权访问。

章节来源

认证流程与注册

  • 登录:用户名+密码校验,账户激活状态校验,成功后签发访问令牌。
  • 注册:校验用户名唯一性,生成密码哈希,创建用户并返回结果。
  • 当前用户:通过 /api/v1/auth/me 获取当前用户信息。
sequenceDiagram
participant FE as "前端"
participant AUTH as "Auth路由"
participant SEC as "security"
participant DB as "数据库"
FE->>AUTH : "POST /auth/login"
AUTH->>DB : "按用户名查询用户"
DB-->>AUTH : "返回User"
AUTH->>SEC : "verify_password()"
SEC-->>AUTH : "校验通过"
AUTH->>SEC : "create_access_token(user.id)"
SEC-->>AUTH : "返回access_token"
AUTH-->>FE : "{access_token, token_type}"
FE->>AUTH : "GET /auth/me"
AUTH->>SEC : "get_current_active_user"
SEC->>DB : "查询当前用户"
DB-->>SEC : "返回User"
SEC-->>AUTH : "返回当前用户"
AUTH-->>FE : "用户信息"

图表来源

章节来源

安全审计与日志

  • 日志配置:按天轮转 app_error 日志,区分控制台与文件输出等级。
  • 异常处理:全局 HTTP 与验证异常记录到日志,便于审计与追踪。
  • 建议:在权限决策点(如 get_current_manager_user增加审计日志记录用户ID、操作、IP、时间与结果。

章节来源

依赖关系分析

  • 路由聚合api/v1/init.py 将各模块路由统一挂载到主应用。
  • 中间件main.py 配置 CORS确保前后端跨域通信。
  • 安全依赖security.py 的依赖函数被各业务路由复用,形成统一的权限控制入口。
graph LR
INIT["api/v1/__init__.py"] --> AUTH["api/v1/auth.py"]
INIT --> STAFF["api/v1/staff.py"]
INIT --> MENUS["api/v1/menus.py"]
MAIN["main.py"] --> INIT
AUTH --> SEC["core/security.py"]
STAFF --> SEC
MENUS --> SEC
SEC --> CFG["core/config.py"]
SEC --> MODELS["models/models.py"]

图表来源

章节来源

性能考虑

  • 令牌解码与用户查询:建议在网关或中间件层缓存近期活跃用户的轻量信息,减少数据库查询压力。
  • 分页与索引:员工与菜单查询使用分页与索引,避免大结果集扫描。
  • CORS 与异常处理:合理配置允许的源与方法,减少预检请求开销。

故障排查指南

  • 401 未授权:检查 Authorization 头是否携带 Bearer token确认 token 未过期。
  • 403 禁止访问:确认用户角色满足 get_current_manager_user 或 get_current_admin_user 要求。
  • 登录失败:检查用户名/密码与账户激活状态。
  • 跨域问题:确认 CORS_ORIGINS 配置与前端访问地址一致。

章节来源

结论

该系统采用简洁明确的 RBAC 模式:以角色驱动的依赖注入实现中间件式权限控制,结合 JWT 令牌与用户激活状态校验,满足后台管理场景下的安全需求。菜单模型的 permission 字段为前端按钮级权限提供了基础。建议后续在服务层引入数据域过滤与权限审计日志,进一步强化数据权限与合规性。

附录

角色权限矩阵(摘要)

  • 管理员admin
    • 员工管理:创建/更新/删除
    • 菜单管理:创建/更新/删除/初始化
  • 科室负责人manager
    • 员工管理:创建/更新/删除
    • 菜单管理:创建/更新/删除(不含初始化)
  • 普通员工staff
    • 员工管理:仅查询列表与详情
    • 菜单管理:查询菜单树/列表(写操作受限)

章节来源

安全最佳实践

  • 强制使用 HTTPS 传输,避免令牌在传输中泄露。
  • 生产环境更换 SECRET_KEY定期轮换。
  • 严格限制 CORS 源,避免跨站风险。
  • 对高敏感操作(如删除)增加二次确认与审计日志。
  • 在服务层增加数据域过滤,防止越权读取。