# 权限控制机制 **本文引用的文件** - [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 ```mermaid graph TB subgraph "后端" A["main.py
应用入口与CORS"] B["api/v1/__init__.py
路由聚合"] C["core/security.py
JWT与权限依赖"] D["api/v1/auth.py
登录/注册/当前用户"] E["models/models.py
User/Menu等模型"] F["core/config.py
JWT配置"] G["core/logging_config.py
日志与审计"] end subgraph "前端" H["frontend/src/router/index.js
路由守卫"] end H --> A A --> B B --> D D --> C C --> E C --> F A --> G ``` 图表来源 - [backend/app/main.py](file://backend/app/main.py#L15-L77) - [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L1-L74) - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) - [backend/app/core/logging_config.py](file://backend/app/core/logging_config.py#L1-L65) 章节来源 - [backend/app/main.py](file://backend/app/main.py#L15-L77) - [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17) ## 核心组件 - JWT 与令牌管理:负责令牌签发、解码、过期控制与用户解析。 - 权限依赖注入:提供“当前用户”、“当前有效用户”、“管理员”、“管理员或经理”的依赖函数,作为路由装饰器实现中间件式权限控制。 - 用户模型与角色:User 模型包含 role 字段,支持 admin、manager、staff 角色。 - 菜单模型与权限标识:Menu 模型包含 permission 字段,用于前端按钮级权限标识。 - 员工与菜单 API:通过依赖注入实现不同角色的访问控制。 章节来源 - [backend/app/core/security.py](file://backend/app/core/security.py#L34-L110) - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [backend/app/models/models.py](file://backend/app/models/models.py#L347-L373) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109) - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150) ## 架构总览 后端通过 FastAPI 的依赖注入系统,在每个路由上声明所需的权限依赖,实现“中间件式”的权限控制。前端通过路由守卫拦截未登录访问,后端通过 OAuth2 Bearer 令牌进行鉴权。 ```mermaid 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 : "执行业务逻辑/返回数据" ``` 图表来源 - [backend/app/core/security.py](file://backend/app/core/security.py#L55-L91) - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L37) - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) ## 详细组件分析 ### JWT 与令牌验证 - 令牌签发:使用 HS256 算法,包含 exp 与 sub(用户ID),默认有效期 8 小时。 - 令牌解码:验证签名与过期时间,失败则抛出凭据无效异常。 - 用户解析:从载荷提取 sub(用户ID),查询数据库获取用户实体并校验 is_active。 - 依赖链路:OAuth2PasswordBearer 提供 tokenUrl,get_current_user 解析用户,get_current_active_user 进一步校验状态。 ```mermaid 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 ``` 图表来源 - [backend/app/core/security.py](file://backend/app/core/security.py#L34-L91) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) 章节来源 - [backend/app/core/security.py](file://backend/app/core/security.py#L34-L91) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) ### RBAC 角色与权限继承 - 角色定义:User.role 支持 admin(管理员)、manager(经理)、staff(普通员工)。 - 权限依赖: - get_current_active_user:校验用户激活状态。 - get_current_manager_user:要求 admin 或 manager。 - get_current_admin_user:要求 admin。 - 路由装饰示例: - 员工管理:创建/更新/删除需管理员或经理权限。 - 菜单管理:创建/更新/删除需管理员或经理权限;初始化默认菜单需管理员权限。 ```mermaid 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 : "返回当前用户" ``` 图表来源 - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109) - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150) 章节来源 - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109) - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150) ### 菜单权限与前端集成 - 菜单模型:Menu 包含 permission 字段,用于前端按钮级权限标识。 - 菜单服务:提供树形结构、列表查询、默认初始化等能力。 - 前端路由守卫:未登录访问会被重定向至登录页,确保前端侧最小暴露面。 ```mermaid 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 : "渲染菜单树/按钮权限" ``` 图表来源 - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L17-L29) - [backend/app/services/menu_service.py](file://backend/app/services/menu_service.py#L16-L29) - [backend/app/models/models.py](file://backend/app/models/models.py#L347-L373) 章节来源 - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L17-L29) - [backend/app/services/menu_service.py](file://backend/app/services/menu_service.py#L16-L29) - [backend/app/models/models.py](file://backend/app/models/models.py#L347-L373) ### 数据权限与业务边界 - 员工管理:仅管理员或经理可增删改;查询列表对所有有效用户开放。 - 菜单管理:对菜单树与列表查询不强制管理员权限,但对写操作(创建/更新/删除/初始化)要求管理员或经理。 - 建议扩展:可在服务层增加“数据域过滤”,例如按用户关联的 staff_id 或 department_id 限制查询范围,避免越权访问。 章节来源 - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L20-L49) - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109) - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L32-L65) - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150) ### 认证流程与注册 - 登录:用户名+密码校验,账户激活状态校验,成功后签发访问令牌。 - 注册:校验用户名唯一性,生成密码哈希,创建用户并返回结果。 - 当前用户:通过 /api/v1/auth/me 获取当前用户信息。 ```mermaid 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 : "用户信息" ``` 图表来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L73) - [backend/app/core/security.py](file://backend/app/core/security.py#L24-L43) - [backend/app/core/security.py](file://backend/app/core/security.py#L55-L91) 章节来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L73) - [backend/app/core/security.py](file://backend/app/core/security.py#L24-L43) - [backend/app/core/security.py](file://backend/app/core/security.py#L55-L91) ### 安全审计与日志 - 日志配置:按天轮转 app_error 日志,区分控制台与文件输出等级。 - 异常处理:全局 HTTP 与验证异常记录到日志,便于审计与追踪。 - 建议:在权限决策点(如 get_current_manager_user)增加审计日志,记录用户ID、操作、IP、时间与结果。 章节来源 - [backend/app/core/logging_config.py](file://backend/app/core/logging_config.py#L1-L65) - [backend/app/main.py](file://backend/app/main.py#L58-L74) ## 依赖关系分析 - 路由聚合:api/v1/__init__.py 将各模块路由统一挂载到主应用。 - 中间件:main.py 配置 CORS,确保前后端跨域通信。 - 安全依赖:security.py 的依赖函数被各业务路由复用,形成统一的权限控制入口。 ```mermaid 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"] ``` 图表来源 - [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17) - [backend/app/main.py](file://backend/app/main.py#L41-L51) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) 章节来源 - [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py#L1-L17) - [backend/app/main.py](file://backend/app/main.py#L41-L51) ## 性能考虑 - 令牌解码与用户查询:建议在网关或中间件层缓存近期活跃用户的轻量信息,减少数据库查询压力。 - 分页与索引:员工与菜单查询使用分页与索引,避免大结果集扫描。 - CORS 与异常处理:合理配置允许的源与方法,减少预检请求开销。 ## 故障排查指南 - 401 未授权:检查 Authorization 头是否携带 Bearer token,确认 token 未过期。 - 403 禁止访问:确认用户角色满足 get_current_manager_user 或 get_current_admin_user 要求。 - 登录失败:检查用户名/密码与账户激活状态。 - 跨域问题:确认 CORS_ORIGINS 配置与前端访问地址一致。 章节来源 - [backend/app/core/security.py](file://backend/app/core/security.py#L55-L110) - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L37) - [backend/app/core/config.py](file://backend/app/core/config.py#L28-L29) ## 结论 该系统采用简洁明确的 RBAC 模式:以角色驱动的依赖注入实现中间件式权限控制,结合 JWT 令牌与用户激活状态校验,满足后台管理场景下的安全需求。菜单模型的 permission 字段为前端按钮级权限提供了基础。建议后续在服务层引入数据域过滤与权限审计日志,进一步强化数据权限与合规性。 ## 附录 ### 角色权限矩阵(摘要) - 管理员(admin) - 员工管理:创建/更新/删除 - 菜单管理:创建/更新/删除/初始化 - 科室负责人(manager) - 员工管理:创建/更新/删除 - 菜单管理:创建/更新/删除(不含初始化) - 普通员工(staff) - 员工管理:仅查询列表与详情 - 菜单管理:查询菜单树/列表(写操作受限) 章节来源 - [backend/app/api/v1/staff.py](file://backend/app/api/v1/staff.py#L68-L109) - [backend/app/api/v1/menus.py](file://backend/app/api/v1/menus.py#L98-L150) - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L110) ### 安全最佳实践 - 强制使用 HTTPS 传输,避免令牌在传输中泄露。 - 生产环境更换 SECRET_KEY,定期轮换。 - 严格限制 CORS 源,避免跨站风险。 - 对高敏感操作(如删除)增加二次确认与审计日志。 - 在服务层增加数据域过滤,防止越权读取。