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

16 KiB
Raw Permalink Blame History

安全认证

**本文引用的文件** - [backend/app/main.py](file://backend/app/main.py) - [backend/app/core/config.py](file://backend/app/core/config.py) - [backend/.env](file://backend/.env) - [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/core/database.py](file://backend/app/core/database.py) - [backend/app/api/v1/__init__.py](file://backend/app/api/v1/__init__.py) - [test_frontend_connection.py](file://test_frontend_connection.py) - [frontend/public/test-api.html](file://frontend/public/test-api.html)

目录

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

简介

本指南面向“医院绩效系统”的后端安全认证开发,聚焦以下主题:

  • JWT 令牌生成、验证与过期处理
  • 密码加密、盐值与安全存储
  • 用户认证流程、权限验证与角色控制
  • CORS 配置、跨域请求处理与安全头策略
  • CSRF、XSS、SQL 注入等常见攻击的缓解思路
  • 会话管理、令牌过期与安全审计
  • OAuth2 集成、第三方认证与 SSO 支持建议
  • 安全测试方法、漏洞扫描与安全加固建议

本指南在不泄露具体代码的前提下,结合仓库现有实现进行系统化梳理,并提供可视化图示与实操建议。

项目结构

后端采用 FastAPI + SQLAlchemy 2.x 异步 ORM 的分层架构,安全相关能力集中在核心模块与认证路由中:

  • 应用入口与中间件FastAPI 应用实例、CORS 中间件、全局异常处理
  • 配置中心:环境变量与运行参数(含 JWT、CORS、数据库
  • 安全模块JWT 编解码、密码哈希、当前用户解析与权限依赖
  • 认证路由:登录、注册、个人信息查询
  • 数据模型与模式:用户表、角色字段、令牌载荷
  • 数据库会话:异步连接与依赖注入
graph TB
subgraph "应用层"
A["FastAPI 应用<br/>main.py"]
B["CORS 中间件<br/>main.py"]
end
subgraph "配置层"
C["系统配置<br/>core/config.py"]
D[".env 环境变量<br/>.env"]
end
subgraph "安全层"
E["JWT/密码/权限<br/>core/security.py"]
end
subgraph "认证路由"
F["认证路由<br/>api/v1/auth.py"]
end
subgraph "数据层"
G["数据库引擎/会话<br/>core/database.py"]
H["用户模型<br/>models/models.py"]
I["数据模式<br/>schemas/schemas.py"]
end
A --> B
A --> F
F --> E
E --> G
G --> H
C --> A
D --> C
E --> I

图表来源

章节来源

核心组件

  • JWT 与密码安全
    • 使用 HS256 算法与对称密钥生成访问令牌;令牌包含过期时间与主体标识
    • 使用 bcrypt 进行密码哈希与校验,自动处理盐值
    • 提供从令牌解析当前用户的依赖函数,配合数据库查询与用户状态校验
  • 认证路由
    • 登录接口:用户名密码校验通过后签发访问令牌
    • 注册接口:检查用户名唯一性,生成密码哈希并持久化
    • 当前用户信息:基于依赖链完成身份与权限校验
  • 配置与中间件
    • CORS 允许指定前端源,支持凭证传递
    • 全局异常处理记录日志并向上抛出
  • 数据模型与模式
    • 用户模型包含角色与激活状态字段,支撑角色与权限控制
    • Pydantic 模式定义 Token 与用户响应结构

章节来源

架构总览

下图展示从浏览器到后端的关键交互路径,涵盖 CORS、认证、权限与数据库访问

sequenceDiagram
participant FE as "前端应用"
participant API as "FastAPI 应用"
participant CORS as "CORS 中间件"
participant AUTH as "认证路由"
participant SEC as "安全模块"
participant DB as "数据库"
FE->>API : "OPTIONS /api/v1/auth/login"
API->>CORS : "CORS 预检检查"
CORS-->>FE : "允许的来源/方法/头"
FE->>AUTH : "POST /api/v1/auth/login"
AUTH->>SEC : "校验用户名/密码"
SEC->>DB : "查询用户并比对哈希"
DB-->>SEC : "返回用户记录"
SEC-->>AUTH : "生成访问令牌"
AUTH-->>FE : "返回 {access_token, token_type}"
FE->>API : "携带 Authorization : Bearer ..."
API->>SEC : "解析 JWT 并加载当前用户"
SEC->>DB : "按 ID 查询用户"
DB-->>SEC : "返回用户"
SEC-->>API : "返回当前用户对象"

图表来源

详细组件分析

JWT 令牌生成与验证

  • 令牌生成
    • 载荷包含过期时间与主体(用户 ID使用对称密钥与指定算法签名
    • 默认有效期可在配置中调整
  • 令牌验证
    • 解析阶段校验签名与过期时间
    • 通过依赖注入从令牌提取主体并查询数据库获取用户对象
    • 若令牌无效或用户不存在,抛出未授权异常
  • 刷新机制
    • 当前实现未提供刷新令牌的专用端点与逻辑
    • 建议引入短期访问令牌与长期刷新令牌,配合黑名单/白名单与安全存储
flowchart TD
Start(["开始"]) --> Build["构建载荷<br/>设置过期时间/主体"]
Build --> Sign["使用 SECRET_KEY + ALGORITHM 签名"]
Sign --> Token["生成 access_token"]
Token --> Verify["接收 access_token"]
Verify --> Decode["解码并校验签名"]
Decode --> Expired{"是否过期?"}
Expired --> |是| Err["返回错误"]
Expired --> |否| LoadUser["按主体查询用户"]
LoadUser --> Found{"用户是否存在?"}
Found --> |否| Err
Found --> |是| Done(["返回当前用户"])

图表来源

章节来源

密码加密、盐值与安全存储

  • 加密算法bcrypt
  • 盐值处理:由 bcrypt 自动生成并嵌入哈希结果
  • 存储:用户模型保存完整哈希字符串
  • 校验:登录时将明文密码与存储哈希进行比对
flowchart TD
In(["输入明文密码"]) --> Hash["bcrypt 生成哈希<br/>自动包含盐值"]
Hash --> Store["存储哈希字符串"]
Store --> VerifyIn(["登录输入明文密码"])
VerifyIn --> Compare["bcrypt 校验明文与存储哈希"]
Compare --> Result{"匹配?"}
Result --> |是| Allow["允许登录"]
Result --> |否| Deny["拒绝登录"]

图表来源

章节来源

用户认证流程与权限验证

  • 认证流程
    • 登录:提交用户名/密码,校验后签发访问令牌
    • 注册:校验用户名唯一性,生成哈希并创建用户
    • 获取当前用户:依赖链解析令牌、校验用户状态、返回用户信息
  • 权限验证
    • 当前活跃用户:校验用户是否启用
    • 管理员:校验角色为 admin
    • 管理者:校验角色为 admin 或 manager
  • 角色控制
    • 用户模型包含角色字段,路由层通过依赖强制权限
sequenceDiagram
participant U as "用户"
participant R as "认证路由"
participant S as "安全模块"
participant M as "模型/数据库"
U->>R : "POST /api/v1/auth/login"
R->>S : "verify_password()"
S->>M : "select user by username"
M-->>S : "返回用户(含哈希)"
S-->>R : "校验通过"
R->>S : "create_access_token(user.id)"
S-->>R : "返回 access_token"
R-->>U : "Token 响应"
U->>R : "GET /api/v1/auth/me"
R->>S : "get_current_active_user()"
S->>S : "decode_token() + 校验过期"
S->>M : "select user by id"
M-->>S : "返回用户"
S-->>R : "返回当前用户"
R-->>U : "用户信息响应"

图表来源

章节来源

CORS 配置与跨域请求处理

  • CORS 中间件已在应用启动时注册,允许指定来源、凭证、方法与头
  • 前端测试脚本通过 OPTIONS 预检与 POST 登录接口验证跨域行为
flowchart TD
Req["浏览器发起请求"] --> Preflight{"是否预检?"}
Preflight --> |是| Options["OPTIONS 预检"]
Options --> Check["CORS 中间件校验 Origin/Method/Headers"]
Check --> Allowed{"允许?"}
Allowed --> |是| Proceed["继续后续请求"]
Allowed --> |否| Block["拒绝请求"]
Preflight --> |否| Proceed

图表来源

章节来源

CSRF、XSS 与 SQL 注入防护

  • CSRF
    • 当前未见专门的 CSRF 令牌或 SameSite Cookie 设置
    • 建议:对无状态 API优先通过严格的 CORS 与来源校验;若使用 Cookie启用 SameSite=Lax|Strict 并配合 CSRF 令牌
  • XSS
    • 建议:前端渲染严格转义、使用 CSP 头限制脚本来源、避免内联脚本
  • SQL 注入
    • 使用 SQLAlchemy 异步 ORM参数化查询默认生效
    • 建议:避免原生 SQL 拼接,统一通过 ORM 或带参查询执行器

章节来源

会话管理、令牌过期与安全审计

  • 会话管理
    • 采用无状态 JWT无需服务端会话存储
  • 令牌过期
    • 令牌包含 exp 字段,默认有效期可配置
    • 建议:在客户端妥善存储 access_token并在 401 时触发重新登录
  • 安全审计
    • 建议:记录登录尝试、令牌签发/失效、敏感操作审计日志
    • 当前全局异常处理器已记录 HTTP 与验证异常

章节来源

OAuth2 集成、第三方认证与 SSO 支持

  • 当前实现基于 OAuth2 密码模式,令牌由后端签发
  • 如需第三方认证(如 OIDC/SAML/SSO建议
    • 引入第三方 SDK 或反向代理(如 Nginx + Keycloak
    • 将外部用户信息映射为内部用户角色与权限
    • 保持对称密钥与算法的安全配置

章节来源

依赖关系分析

  • 组件耦合
    • 认证路由依赖安全模块与数据库会话
    • 安全模块依赖配置与数据库,提供多级权限依赖
    • 应用入口集中注册 CORS 与路由,异常处理统一
  • 外部依赖
    • JWT 编解码、密码哈希、异步数据库驱动
  • 潜在问题
    • 未发现循环依赖
    • CORS 与安全头策略需与前端部署域名一致
graph LR
Auth["api/v1/auth.py"] --> Sec["core/security.py"]
Sec --> DB["core/database.py"]
Sec --> Model["models/models.py"]
Sec --> Conf["core/config.py"]
Main["app/main.py"] --> CORS["CORS 中间件"]
Main --> Auth
Conf --> Main
Env[".env"] --> Conf

图表来源

章节来源

性能考量

  • JWT 解析与数据库查询
    • 令牌解析为内存操作;用户查询需一次数据库往返
    • 建议:为用户表与索引字段建立合适索引,减少查询开销
  • CORS 预检缓存
    • 合理设置预检缓存时间,减少重复 OPTIONS 请求
  • 会话与令牌
    • 无状态 JWT 降低服务端压力;注意令牌大小与负载字段精简

故障排查指南

  • 登录失败
    • 检查用户名/密码是否正确,确认用户处于启用状态
    • 查看后端日志定位异常
  • 跨域问题
    • 确认前端 Origin 是否在允许列表,预检请求是否返回允许头
  • 令牌无效
    • 检查令牌是否过期、算法与密钥是否匹配、主体是否正确
  • 权限不足
    • 确认用户角色满足所需权限依赖

章节来源

结论

本项目在安全认证方面具备清晰的分层与职责划分JWT 与 bcrypt 的组合提供了可靠的令牌与密码安全权限依赖链实现了基于角色的访问控制CORS 中间件与异常处理提升了可用性与可观测性。建议在生产环境中进一步完善令牌刷新、CSRF 防护、安全头策略、审计日志与第三方认证集成,以满足更严格的安全要求。

附录

  • 安全测试清单
    • CORS 配置验证(预检与实际请求)
    • 登录与鉴权端点的 401/403 场景
    • 令牌过期与权限变更后的行为
    • SQL 注入与 XSS 基线扫描
  • 安全加固建议
    • 生产环境替换默认密钥与最小长度要求
    • 引入短期访问令牌与刷新令牌机制
    • 启用 HTTPS、安全响应头、CSP
    • 对高危操作增加二次确认与审计