# 用户认证系统 **本文引用的文件** - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py) - [backend/app/core/security.py](file://backend/app/core/security.py) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py) - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/app/core/config.py](file://backend/app/core/config.py) - [backend/app/main.py](file://backend/app/main.py) - [frontend/src/api/auth.js](file://frontend/src/api/auth.js) - [frontend/src/api/request.js](file://frontend/src/api/request.js) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js) - [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue) - [backend/requirements.txt](file://backend/requirements.txt) - [test_frontend_connection.py](file://test_frontend_connection.py) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向“医院绩效系统”的用户认证子系统,提供从登录注册到权限校验、JWT 令牌管理、会话与状态管理、前后端交互流程、错误处理与安全策略的完整说明。内容覆盖后端 FastAPI 接口、前端 Vue/Element Plus 交互、Pinia 状态管理、以及数据库模型与安全策略。 ## 项目结构 认证系统由后端 API 路由、安全模块、数据模型与 Pydantic Schema,以及前端请求封装、状态管理与登录界面组成。整体采用 OAuth2 密码模式,使用 JWT 进行无状态鉴权;前端通过 Axios 拦截器统一注入 Authorization 头,后端通过依赖注入解析令牌并校验用户状态。 ```mermaid graph TB subgraph "前端" FE_Login["Login.vue
登录界面"] FE_Store["user.js
Pinia Store"] FE_API_Auth["auth.js
认证接口封装"] FE_Request["request.js
Axios 实例与拦截器"] end subgraph "后端" BE_Main["main.py
应用入口与CORS"] BE_Router_Auth["api/v1/auth.py
认证路由"] BE_Security["core/security.py
JWT/密码/依赖"] BE_Schema["schemas/schemas.py
认证数据模型"] BE_Models["models/models.py
User/Menu 等模型"] BE_Config["core/config.py
JWT/跨域/分页配置"] end FE_Login --> FE_Store FE_Store --> FE_API_Auth FE_API_Auth --> FE_Request FE_Request --> BE_Main BE_Main --> BE_Router_Auth BE_Router_Auth --> BE_Security BE_Security --> BE_Schema BE_Security --> BE_Models BE_Router_Auth --> BE_Schema BE_Router_Auth --> BE_Models BE_Main --> BE_Config ``` 图表来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L1-L74) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L313-L346) - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [backend/app/core/config.py](file://backend/app/core/config.py#L9-L38) - [backend/app/main.py](file://backend/app/main.py#L15-L77) - [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49) - [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L1-L155) 章节来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L1-L74) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L313-L346) - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [backend/app/core/config.py](file://backend/app/core/config.py#L9-L38) - [backend/app/main.py](file://backend/app/main.py#L15-L77) - [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49) - [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L1-L155) ## 核心组件 - 认证路由与接口 - 登录:接收表单数据,校验用户名/密码与账户状态,签发 JWT。 - 注册:校验用户名唯一性,生成密码哈希,写入用户记录。 - 当前用户:基于依赖注入解析 JWT 并返回用户信息。 - 安全模块 - 密码哈希:bcrypt。 - JWT:encode/decode,OAuth2 密码流 tokenUrl。 - 依赖:获取当前用户、校验激活状态、校验管理员/经理角色。 - 数据模型与 Schema - User 模型:id、username、password_hash、role、is_active、last_login 等。 - 认证 Schema:UserLogin、UserCreate、Token、UserResponse。 - 前端交互 - 登录表单:Element Plus 表单校验与按钮触发。 - Pinia Store:保存 token、持久化 localStorage、登出重定向。 - Axios 拦截器:自动注入 Authorization: Bearer token,401 跳转登录。 章节来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L74) - [backend/app/core/security.py](file://backend/app/core/security.py#L24-L110) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L315-L346) - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L63-L89) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L10-L39) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L14-L26) ## 架构总览 认证系统遵循 OAuth2 密码模式,后端通过 FastAPI 的依赖注入解析 JWT,前端通过 Axios 拦截器统一携带 Bearer Token。CORS 在后端全局中间件开启,允许前端开发源访问。 ```mermaid sequenceDiagram participant U as "用户浏览器" participant LV as "Login.vue" participant US as "user.js" participant AU as "auth.js" participant AX as "request.js" participant API as "auth.py" participant SEC as "security.py" participant DB as "数据库" U->>LV : 输入用户名/密码并点击登录 LV->>US : 调用 store.login(username, password) US->>AU : 调用 login({username, password}) AU->>AX : POST /api/v1/auth/login (表单) AX->>API : 发送请求 API->>SEC : verify_password() 校验密码 API->>DB : 查询用户并检查 is_active API-->>AX : 返回 {access_token, token_type} AX-->>US : 返回 access_token US->>US : localStorage.setItem('token', access_token) US-->>LV : 登录成功,跳转首页 ``` 图表来源 - [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L73-L89) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20) - [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L4-L11) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L14-L26) - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L37) - [backend/app/core/security.py](file://backend/app/core/security.py#L24-L31) ## 详细组件分析 ### 后端认证路由与接口 - 登录接口 - 方法与路径:POST /api/v1/auth/login - 请求体:OAuth2 表单(username/password),或前端封装为 application/x-www-form-urlencoded。 - 处理逻辑:查询用户、校验密码、检查 is_active、签发 access_token。 - 响应:Token 模型(access_token、token_type=bearer)。 - 注册接口 - 方法与路径:POST /api/v1/auth/register - 请求体:UserCreate(username、password、staff_id、role)。 - 处理逻辑:检查用户名唯一性、生成密码哈希、写入 User 记录。 - 响应:通用响应(code/message/data)。 - 当前用户接口 - 方法与路径:GET /api/v1/auth/me - 依赖:get_current_active_user(校验令牌与激活状态)。 - 响应:UserResponse。 章节来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L74) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L315-L346) ### 安全模块与 JWT 策略 - OAuth2 密码模式 - tokenUrl:/api/v1/auth/login。 - 前端通过 OAuth2PasswordRequestForm 或自定义表单提交。 - 密码与令牌 - 密码哈希:bcrypt。 - 令牌载荷:sub(用户 id)、exp(过期时间)。 - 算法与密钥:配置项 ALGORITHM/SECRET_KEY。 - 依赖链 - get_current_user:从 Authorization 解析 JWT,查询用户。 - get_current_active_user:校验 is_active。 - get_current_admin_user / get_current_manager_user:校验角色。 - 配置 - ACCESS_TOKEN_EXPIRE_MINUTES:默认约 8 小时。 - API_PREFIX:/api/v1。 章节来源 - [backend/app/core/security.py](file://backend/app/core/security.py#L21-L110) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) - [backend/app/main.py](file://backend/app/main.py#L41-L48) ### 数据模型与权限枚举 - User 模型字段 - id、username(唯一)、password_hash、role、is_active、last_login、created_at/updated_at。 - 角色与权限 - role:admin(管理员)、manager(经理)、staff(普通员工)。 - 依赖 get_current_manager_user 用于限制“管理员或经理”操作。 - 菜单与权限标识 - Menu 模型含 permission 字段,可用于前端菜单/按钮级权限控制(与后端依赖配合)。 章节来源 - [backend/app/models/models.py](file://backend/app/models/models.py#L244-L261) - [backend/app/core/security.py](file://backend/app/core/security.py#L94-L109) - [backend/app/models/models.py](file://backend/app/models/models.py#L347-L372) ### 前端交互与状态管理 - 登录界面 - Element Plus 表单校验、输入框、按钮与回车事件。 - Axios 拦截器 - 请求:自动注入 Authorization: Bearer token。 - 响应:401 清除本地 token 并跳转登录页。 - Pinia Store - 登录:调用后端登录接口,保存 token 到内存与 localStorage。 - 获取用户:调用 /auth/me,缓存用户信息。 - 登出:清除 token 与用户信息,移除 localStorage,跳转登录页。 章节来源 - [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L63-L89) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L14-L26) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L10-L39) ### API 接口定义与参数说明 - 登录 - 方法:POST - 路径:/api/v1/auth/login - 认证:OAuth2 表单或 application/x-www-form-urlencoded - 请求体字段:username、password - 响应体字段:access_token、token_type - 注册 - 方法:POST - 路径:/api/v1/auth/register - 请求体字段:username、password、staff_id、role - 响应体字段:code、message、data.id - 当前用户 - 方法:GET - 路径:/api/v1/auth/me - 认证:Authorization: Bearer - 响应体字段:id、username、role、is_active、last_login、created_at 章节来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L17-L74) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L315-L346) ### 错误处理与安全防护 - 后端错误 - 401 未授权:凭据无效或令牌解析失败。 - 403 禁止访问:账户被禁用或权限不足。 - 400 参数错误:用户名已存在、用户不存在等。 - 前端错误 - 401:提示“登录已过期,请重新登录”,清除 token 并跳转登录页。 - 通用错误:弹出 ElMessage 提示。 - 安全策略 - 密码使用 bcrypt 哈希。 - JWT 使用 HS256 算法与强密钥(生产环境需替换默认密钥)。 - CORS 允许指定前端源。 - 令牌过期时间可配置,默认约 8 小时。 章节来源 - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L30-L34) - [backend/app/core/security.py](file://backend/app/core/security.py#L55-L91) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L38-L62) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) - [backend/app/main.py](file://backend/app/main.py#L41-L48) ## 依赖分析 - 后端依赖 - FastAPI + SQLAlchemy 异步 + Pydantic + python-jose + bcrypt。 - CORS 中间件开启,允许前端开发源。 - 前端依赖 - axios、Element Plus、Vue Router、Pinia。 - 认证依赖链 - auth.py 依赖 security.py 的 verify_password、create_access_token、get_current_active_user。 - security.py 依赖 config.py 的 SECRET_KEY、ALGORITHM、ACCESS_TOKEN_EXPIRE_MINUTES。 - 前端 auth.js 依赖 request.js 的 baseURL 与拦截器。 ```mermaid graph LR RQ["requirements.txt
依赖声明"] --> BE_SEC["security.py"] BE_MAIN["main.py"] --> BE_AUTH["auth.py"] BE_AUTH --> BE_SEC BE_SEC --> BE_CFG["config.py"] FE_REQ["request.js"] --> FE_AUTH["auth.js"] FE_AUTH --> FE_STORE["user.js"] FE_STORE --> FE_LOGIN["Login.vue"] ``` 图表来源 - [backend/requirements.txt](file://backend/requirements.txt#L1-L17) - [backend/app/main.py](file://backend/app/main.py#L41-L48) - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L10-L12) - [backend/app/core/security.py](file://backend/app/core/security.py#L13-L15) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L6-L12) - [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L2) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L4) 章节来源 - [backend/requirements.txt](file://backend/requirements.txt#L1-L17) - [backend/app/main.py](file://backend/app/main.py#L41-L48) - [backend/app/api/v1/auth.py](file://backend/app/api/v1/auth.py#L10-L12) - [backend/app/core/security.py](file://backend/app/core/security.py#L13-L15) - [backend/app/core/config.py](file://backend/app/core/config.py#L23-L26) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L6-L12) - [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L2) - [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L4) ## 性能考虑 - 令牌有效期:默认约 8 小时,建议根据业务场景调整,避免频繁刷新。 - 密码哈希:bcrypt 默认成本适中,生产环境可根据硬件能力提升成本。 - 数据库连接池:配置 DATABASE_POOL_SIZE 与 MAX_OVERFLOW,确保高并发下的连接稳定性。 - 前端拦截器:统一注入 Authorization,减少重复代码与错误。 ## 故障排查指南 - 登录失败 - 确认用户名/密码正确,账户处于激活状态。 - 检查后端日志与 401/403 错误原因。 - CORS 问题 - 确认后端 CORS_ORIGINS 包含前端地址,测试脚本验证 OPTIONS 预检。 - Token 过期或 401 - 前端拦截器会自动清除 token 并跳转登录页,重新登录获取新令牌。 - 本地开发 - 前端通过 Vite 代理访问后端 /api,确保 baseURL 与后端 API_PREFIX 一致。 章节来源 - [test_frontend_connection.py](file://test_frontend_connection.py#L38-L74) - [frontend/src/api/request.js](file://frontend/src/api/request.js#L38-L62) - [backend/app/main.py](file://backend/app/main.py#L41-L48) ## 结论 该认证系统采用 OAuth2 密码模式与 JWT 无状态鉴权,结合 bcrypt 密码哈希与严格的依赖校验,实现了登录注册、权限控制与会话管理。前端通过 Axios 拦截器与 Pinia Store 完成令牌注入与状态维护,整体结构清晰、扩展性强,适合在医院绩效系统中作为统一认证层使用。 ## 附录 - 默认凭证 - 用户名:admin - 密码:admin123 - API 文档 - Swagger UI:http://localhost:8000/api/v1/docs - ReDoc:http://localhost:8000/api/v1/redoc