Files
dashboard/.qoder/repowiki/zh/content/前端组件/页面组件/登录页面.md
T
2026-06-30 14:46:52 +08:00

480 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 登录页面
<cite>
**本文档引用的文件**
- [frontend/src/views/login/index.vue](file://frontend/src/views/login/index.vue)
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js)
- [frontend/src/utils/auth.js](file://frontend/src/utils/auth.js)
- [frontend/src/utils/request.js](file://frontend/src/utils/request.js)
- [frontend/src/router/index.js](file://frontend/src/router/index.js)
- [frontend/src/utils/tabs.js](file://frontend/src/utils/tabs.js)
- [backend/src/routes/auth.js](file://backend/src/routes/auth.js)
- [backend/src/utils/jwt.js](file://backend/src/utils/jwt.js)
- [backend/src/middleware/auth.js](file://backend/src/middleware/auth.js)
- [backend/src/utils/password.js](file://backend/src/utils/password.js)
- [backend/src/utils/response.js](file://backend/src/utils/response.js)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 简介
本文件面向登录页面的完整技术文档,涵盖前端登录表单设计、字段验证、提交处理与响应处理;后端认证机制、JWT 令牌生成与校验;登录状态持久化与路由守卫;安全措施(密码哈希、防暴力破解思路、会话管理);登录成功后的路由跳转、权限检查与用户信息初始化流程;错误处理、用户体验优化与移动端适配等实现细节。
## 项目结构
登录功能涉及前后端协作:前端负责表单渲染、输入校验、请求发送与状态持久化;后端负责用户鉴权、密码校验、JWT 签发与中间件保护。
```mermaid
graph TB
subgraph "前端"
LoginView["登录视图<br/>frontend/src/views/login/index.vue"]
AuthAPI["认证 API<br/>frontend/src/api/auth.js"]
AuthUtil["认证工具<br/>frontend/src/utils/auth.js"]
RequestUtil["HTTP 请求封装<br/>frontend/src/utils/request.js"]
Router["路由守卫<br/>frontend/src/router/index.js"]
TabsUtil["标签页工具<br/>frontend/src/utils/tabs.js"]
end
subgraph "后端"
AuthRoute["认证路由<br/>backend/src/routes/auth.js"]
JWTUtil["JWT 工具<br/>backend/src/utils/jwt.js"]
PasswordUtil["密码工具<br/>backend/src/utils/password.js"]
AuthMW["认证中间件<br/>backend/src/middleware/auth.js"]
RespUtil["响应封装<br/>backend/src/utils/response.js"]
end
LoginView --> AuthAPI
AuthAPI --> RequestUtil
RequestUtil --> AuthRoute
AuthRoute --> JWTUtil
AuthRoute --> PasswordUtil
AuthRoute --> RespUtil
RequestUtil --> AuthUtil
Router --> AuthUtil
Router --> TabsUtil
AuthRoute --> AuthMW
```
图表来源
- [frontend/src/views/login/index.vue:100-151](file://frontend/src/views/login/index.vue#L100-L151)
- [frontend/src/api/auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
- [frontend/src/utils/request.js:1-72](file://frontend/src/utils/request.js#L1-L72)
- [frontend/src/router/index.js:1-91](file://frontend/src/router/index.js#L1-L91)
- [backend/src/routes/auth.js:1-112](file://backend/src/routes/auth.js#L1-L112)
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
- [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
章节来源
- [frontend/src/views/login/index.vue:1-453](file://frontend/src/views/login/index.vue#L1-L453)
- [frontend/src/api/auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
- [frontend/src/utils/auth.js:1-99](file://frontend/src/utils/auth.js#L1-L99)
- [frontend/src/utils/request.js:1-72](file://frontend/src/utils/request.js#L1-L72)
- [frontend/src/router/index.js:1-91](file://frontend/src/router/index.js#L1-L91)
- [backend/src/routes/auth.js:1-112](file://backend/src/routes/auth.js#L1-L112)
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
- [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
## 核心组件
- 登录视图:负责表单渲染、字段校验、提交处理与成功/失败反馈。
- 认证 API:封装登录接口调用,统一请求参数格式。
- 认证工具:负责本地 Token 与用户信息的读取、设置、清理与解析。
- 请求封装:全局注入 Authorization 头、处理 401 自动跳转登录。
- 路由守卫:控制访问权限、超时自动登出、超级管理员限制。
- 后端认证路由:处理登录、获取当前用户、修改密码。
- JWT 工具:签发与解码 Access Token,定义 TTL。
- 密码工具:PBKDF2 哈希与安全比对。
- 认证中间件:校验 Bearer Token 并注入用户上下文。
章节来源
- [frontend/src/views/login/index.vue:100-151](file://frontend/src/views/login/index.vue#L100-L151)
- [frontend/src/api/auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
- [frontend/src/utils/auth.js:1-99](file://frontend/src/utils/auth.js#L1-L99)
- [frontend/src/utils/request.js:1-72](file://frontend/src/utils/request.js#L1-L72)
- [frontend/src/router/index.js:64-88](file://frontend/src/router/index.js#L64-L88)
- [backend/src/routes/auth.js:24-77](file://backend/src/routes/auth.js#L24-L77)
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
- [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
## 架构总览
登录流程在前后端之间形成闭环:前端收集凭据并发起登录请求,后端验证用户与密码,签发 JWT,前端保存 Token 并重定向到首页;后续请求通过请求拦截器携带 Token,后端中间件校验并注入用户信息。
```mermaid
sequenceDiagram
participant U as "用户"
participant LV as "登录视图<br/>index.vue"
participant API as "认证 API<br/>auth.js"
participant REQ as "请求封装<br/>request.js"
participant AR as "认证路由<br/>routes/auth.js"
participant PW as "密码工具<br/>password.js"
participant JW as "JWT 工具<br/>jwt.js"
participant AU as "认证工具<br/>utils/auth.js"
participant RT as "路由守卫<br/>router/index.js"
U->>LV : 输入账号/密码并点击登录
LV->>LV : 表单校验
LV->>API : 调用登录接口
API->>REQ : 发送 POST /api/auth/login
REQ->>AR : 携带 Authorization非登录时
AR->>PW : 验证密码
AR->>JW : 签发 Access Token
AR-->>REQ : 返回 {access_token, user, expires_in}
REQ-->>LV : 返回响应数据
LV->>AU : setToken(access_token)
LV->>AU : setUser(user)
LV->>RT : 清空标签页缓存并跳转首页
```
图表来源
- [frontend/src/views/login/index.vue:123-150](file://frontend/src/views/login/index.vue#L123-L150)
- [frontend/src/api/auth.js:3-12](file://frontend/src/api/auth.js#L3-L12)
- [frontend/src/utils/request.js:12-25](file://frontend/src/utils/request.js#L12-L25)
- [backend/src/routes/auth.js:24-64](file://backend/src/routes/auth.js#L24-L64)
- [backend/src/utils/password.js:16-34](file://backend/src/utils/password.js#L16-L34)
- [backend/src/utils/jwt.js:7-17](file://backend/src/utils/jwt.js#L7-L17)
- [frontend/src/utils/auth.js:8-26](file://frontend/src/utils/auth.js#L8-L26)
- [frontend/src/router/index.js:82-85](file://frontend/src/router/index.js#L82-L85)
## 详细组件分析
### 登录视图(表单设计与交互)
- 表单字段:
- 账号:必填,自动去除首尾空白。
- 密码:必填,支持显示/隐藏切换,回车触发提交。
- 校验规则:账号与密码均为必填项。
- 提交流程:
- 触发校验,通过后进入加载态。
- 调用登录 API,接收响应后:
- 若返回 access_token,则保存 Token 与用户信息,清空标签页缓存,跳转首页。
- 否则提示失败消息。
- 最终关闭加载态。
```mermaid
flowchart TD
Start(["开始"]) --> Validate["表单校验"]
Validate --> Valid{"校验通过?"}
Valid --> |否| ShowError["显示错误提示"]
Valid --> |是| Loading["设置加载态"]
Loading --> CallAPI["调用登录 API"]
CallAPI --> RespOK{"响应包含 access_token"}
RespOK --> |是| SaveToken["保存 Token 与用户信息"]
SaveToken --> ClearTabs["清空标签页缓存"]
ClearTabs --> Redirect["跳转首页"]
RespOK --> |否| Toast["提示失败消息"]
Toast --> End(["结束"])
Redirect --> End
ShowError --> End
```
图表来源
- [frontend/src/views/login/index.vue:118-150](file://frontend/src/views/login/index.vue#L118-L150)
章节来源
- [frontend/src/views/login/index.vue:45-91](file://frontend/src/views/login/index.vue#L45-L91)
- [frontend/src/views/login/index.vue:118-150](file://frontend/src/views/login/index.vue#L118-L150)
### 认证 API 与请求封装
- 认证 API
- 登录接口:POST /api/auth/login,参数包含 username 与 password。
- 修改密码接口:PUT /api/auth/password,参数包含 old_password 与 new_password。
- 请求封装:
- 默认 baseURL 为 /api,超时 10 秒。
- 请求拦截器:非登录接口自动附加 Authorization: Bearer token。
- 响应拦截器:
- code=0 的业务错误:统一弹出错误提示并拒绝 Promise。
- 401 未授权:清除本地认证信息,跳转登录页并附带 redirect 参数。
- 403 无权限:提示无权限。
- 其他错误:统一提示网络错误。
```mermaid
sequenceDiagram
participant LV as "登录视图"
participant API as "认证 API"
participant REQ as "请求封装"
participant AR as "认证路由"
participant RESP as "响应拦截器"
LV->>API : login({username,password})
API->>REQ : request({url : '/auth/login', method : 'post'})
REQ->>AR : 发送请求
AR-->>REQ : 返回 {code,data,msg}
REQ->>RESP : 统一处理响应
RESP-->>LV : 成功数据或抛错
```
图表来源
- [frontend/src/api/auth.js:3-12](file://frontend/src/api/auth.js#L3-L12)
- [frontend/src/utils/request.js:12-69](file://frontend/src/utils/request.js#L12-L69)
章节来源
- [frontend/src/api/auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
- [frontend/src/utils/request.js:1-72](file://frontend/src/utils/request.js#L1-L72)
### 认证工具(Token 与用户信息)
- Token 存储键名:localStorage 中的 dashboard_access_token。
- 用户信息存储键名:localStorage 中的 dashboard_user。
- 主要方法:
- 获取/设置/清除 Token。
- 设置/获取/清除 用户信息。
- 从 Token 解析用户信息(sub、username、is_super_admin)。
- 判断 Token 是否过期(基于 exp)。
- 清除认证信息并清空标签页缓存。
- 判断是否超级管理员。
```mermaid
flowchart TD
GetToken["获取 Token"] --> HasToken{"存在 Token"}
HasToken --> |否| NullUser["返回 null 或兜底解析"]
HasToken --> |是| ParseExp["解析 exp 时间戳"]
ParseExp --> Expired{"是否过期?"}
Expired --> |是| Clear["清除认证信息"]
Expired --> |否| ReturnUser["返回用户信息"]
Clear --> NullUser
```
图表来源
- [frontend/src/utils/auth.js:4-99](file://frontend/src/utils/auth.js#L4-L99)
章节来源
- [frontend/src/utils/auth.js:1-99](file://frontend/src/utils/auth.js#L1-L99)
### 后端认证路由与中间件
- 登录接口:
- 校验必填参数,去空白用户名。
- 查询用户并检查状态。
- 使用 PBKDF2 验证密码。
- 更新最近登录时间,签发 Access Token,返回用户信息与过期时间。
- 获取当前用户接口:受认证中间件保护,返回用户字典。
- 修改密码接口:校验旧密码与新密码长度,更新密码哈希。
- 认证中间件:
- 校验 Authorization 头是否以 Bearer 开头。
- 解码 JWT,注入 req.userid、username、is_super_admin)。
- 处理过期与无效 Token 场景。
```mermaid
sequenceDiagram
participant CL as "客户端"
participant AR as "认证路由"
participant DB as "数据库模型"
participant PW as "密码工具"
participant JW as "JWT 工具"
CL->>AR : POST /api/auth/login
AR->>DB : 查找用户
AR->>PW : verifyPassword(password, hash)
PW-->>AR : 验证结果
AR->>DB : 更新最近登录时间
AR->>JW : createAccessToken(user)
JW-->>AR : 返回 access_token
AR-->>CL : 返回 {access_token,user,expires_in}
```
图表来源
- [backend/src/routes/auth.js:24-64](file://backend/src/routes/auth.js#L24-L64)
- [backend/src/utils/password.js:16-34](file://backend/src/utils/password.js#L16-L34)
- [backend/src/utils/jwt.js:7-17](file://backend/src/utils/jwt.js#L7-L17)
章节来源
- [backend/src/routes/auth.js:24-112](file://backend/src/routes/auth.js#L24-L112)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37)
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
### 路由守卫与权限控制
- 守卫逻辑:
- 需要认证的路由:若无 Token 或已过期,清除认证并跳转登录页,附带 redirect。
- 超级管理员限制:当目标路由标记 requiresSuperAdmin 且当前用户非超级管理员时,重定向首页。
- 已登录用户访问 /login:若 Token 有效则重定向首页。
- 与认证工具配合:使用 isTokenExpired 与 isSuperAdmin 判断。
```mermaid
flowchart TD
Enter(["进入路由"]) --> NeedAuth{"需要认证?"}
NeedAuth --> |否| Next["放行"]
NeedAuth --> |是| HasToken{"有有效 Token"}
HasToken --> |否| GoLogin["跳转登录并附带 redirect"]
HasToken --> |是| SuperReq{"需要超级管理员?"}
SuperReq --> |是| IsSuper{"当前用户是超级管理员?"}
IsSuper --> |否| Home["重定向首页"]
IsSuper --> |是| Next
GoLogin --> End(["结束"])
Home --> End
Next --> End
```
图表来源
- [frontend/src/router/index.js:64-88](file://frontend/src/router/index.js#L64-L88)
- [frontend/src/utils/auth.js:73-75](file://frontend/src/utils/auth.js#L73-L75)
章节来源
- [frontend/src/router/index.js:64-88](file://frontend/src/router/index.js#L64-L88)
- [frontend/src/utils/auth.js:73-75](file://frontend/src/utils/auth.js#L73-L75)
### JWT 令牌机制
- 签发:
- Payload 包含 sub、username、is_super_admin、iat、exp。
- TTL 固定为 12 小时,exp 以秒计算。
- 校验:
- 中间件使用 HS256 算法验证签名与过期时间。
- 过期或无效时返回 401。
- 前端解析:
- 从 Token 解析 exp 并转换为毫秒时间戳判断过期。
- 支持从 Token 兜底解析用户信息(sub、username、is_super_admin)。
```mermaid
classDiagram
class JWTUtil {
+createAccessToken(user)
+decodeToken(token)
+getTokenTtlSeconds()
}
class AuthMW {
+authMiddleware(req,res,next)
+requireSuperAdmin(req,res,next)
}
class AuthUtils {
+getUserFromToken(token)
+getTokenExpiresAt(token)
+isTokenExpired(token)
}
AuthMW --> JWTUtil : "校验 Token"
AuthUtils --> JWTUtil : "解析 payload"
```
图表来源
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [frontend/src/utils/auth.js:52-99](file://frontend/src/utils/auth.js#L52-L99)
章节来源
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [frontend/src/utils/auth.js:52-99](file://frontend/src/utils/auth.js#L52-L99)
### 安全措施
- 密码存储与校验:
- 使用 PBKDF2(迭代次数、盐、密钥长度、摘要算法)进行哈希。
- 安全比对采用定时常量时间比较,降低侧信道攻击风险。
- 传输安全:
- 所有非登录接口自动附加 Bearer Token,避免明文传输。
- 建议在生产环境启用 HTTPS。
- 会话管理:
- 前端仅保存 Token 与用户信息于 localStorage/sessionStorage。
- 401 时自动清除认证信息并跳转登录。
- 路由守卫在进入受保护路由前校验 Token 有效性。
- 防暴力破解(建议):
- 后端可引入速率限制与账户锁定策略(当前实现未见显式限制逻辑)。
章节来源
- [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37)
- [frontend/src/utils/request.js:44-59](file://frontend/src/utils/request.js#L44-L59)
- [frontend/src/router/index.js:68-73](file://frontend/src/router/index.js#L68-L73)
### 错误处理与用户体验
- 登录错误:
- 前端:表单校验失败提示;接口返回错误提示;异常捕获与日志输出。
- 后端:参数缺失、用户不存在/禁用、密码错误、内部异常均返回统一结构。
- 401 自动跳转:
- 响应拦截器检测 401,清除本地认证,跳转登录页并附带 redirect。
- 403 权限不足:
- 弹出提示并阻止导航。
- 加载态与交互:
- 登录按钮显示加载态,避免重复提交。
- 提示文案统一使用 Element Plus 的消息组件。
章节来源
- [frontend/src/views/login/index.vue:123-150](file://frontend/src/views/login/index.vue#L123-L150)
- [frontend/src/utils/request.js:27-69](file://frontend/src/utils/request.js#L27-L69)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
### 移动端适配
- 视口与布局:
- 登录卡片最大宽度限制,保证在小屏设备上不拥挤。
- 使用相对单位与弹性布局,确保在不同屏幕尺寸下保持良好体验。
- 交互优化:
- 输入框自动聚焦与回车提交,减少移动端输入成本。
- 按钮尺寸与间距适中,便于触摸点击。
章节来源
- [frontend/src/views/login/index.vue:153-453](file://frontend/src/views/login/index.vue#L153-L453)
## 依赖关系分析
- 前端模块耦合:
- 登录视图依赖认证 API 与认证工具。
- 认证 API 依赖请求封装。
- 请求封装依赖认证工具(读取 Token)。
- 路由守卫依赖认证工具与标签页工具。
- 后端模块耦合:
- 认证路由依赖模型、密码工具、JWT 工具与响应封装。
- 认证中间件依赖 JWT 工具。
- 可能的循环依赖:
- 当前模块划分清晰,未发现循环依赖迹象。
```mermaid
graph LR
LV["登录视图"] --> API["认证 API"]
API --> REQ["请求封装"]
REQ --> AU["认证工具"]
RT["路由守卫"] --> AU
RT --> TU["标签页工具"]
AR["认证路由"] --> PW["密码工具"]
AR --> JW["JWT 工具"]
AR --> RU["响应封装"]
AR --> MW["认证中间件"]
```
图表来源
- [frontend/src/views/login/index.vue:100-151](file://frontend/src/views/login/index.vue#L100-L151)
- [frontend/src/api/auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
- [frontend/src/utils/request.js:1-72](file://frontend/src/utils/request.js#L1-L72)
- [frontend/src/router/index.js:1-91](file://frontend/src/router/index.js#L1-L91)
- [backend/src/routes/auth.js:1-112](file://backend/src/routes/auth.js#L1-L112)
- [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37)
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
章节来源
- [frontend/src/views/login/index.vue:100-151](file://frontend/src/views/login/index.vue#L100-L151)
- [frontend/src/api/auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
- [frontend/src/utils/request.js:1-72](file://frontend/src/utils/request.js#L1-L72)
- [frontend/src/router/index.js:1-91](file://frontend/src/router/index.js#L1-L91)
- [backend/src/routes/auth.js:1-112](file://backend/src/routes/auth.js#L1-L112)
- [backend/src/utils/password.js:1-37](file://backend/src/utils/password.js#L1-L37)
- [backend/src/utils/jwt.js:1-28](file://backend/src/utils/jwt.js#L1-L28)
- [backend/src/middleware/auth.js:1-36](file://backend/src/middleware/auth.js#L1-L36)
- [backend/src/utils/response.js:1-25](file://backend/src/utils/response.js#L1-L25)
## 性能考虑
- Token TTL:12 小时,平衡安全性与用户体验。
- 请求拦截器:避免重复设置 Authorization,减少不必要的网络开销。
- 前端解析:仅在需要时解析 Token,避免频繁计算。
- 建议优化:
- 对频繁访问的受保护接口,可在路由守卫中加入缓存策略(如短期缓存用户信息)。
- 后端可引入登录失败计数与临时封禁策略,缓解暴力破解风险。
## 故障排除指南
- 登录失败:
- 检查用户名/密码是否为空,确认后端返回的错误消息。
- 确认数据库中用户状态正常且密码哈希正确。
- 401 未授权:
- 检查请求头是否包含正确的 Bearer Token。
- 确认 Token 未过期,必要时重新登录。
- 403 无权限:
- 确认当前用户具备所需权限(超级管理员)。
- 页面跳转异常:
- 检查路由守卫逻辑与 redirect 参数传递。
- 确认标签页缓存清理是否成功。
章节来源
- [frontend/src/utils/request.js:44-59](file://frontend/src/utils/request.js#L44-L59)
- [frontend/src/router/index.js:68-73](file://frontend/src/router/index.js#L68-L73)
- [backend/src/middleware/auth.js:21-25](file://backend/src/middleware/auth.js#L21-L25)
## 结论
该登录系统从前端表单到后端认证形成完整的闭环,具备良好的可维护性与扩展性。前端通过统一的请求封装与路由守卫保障了安全性与用户体验;后端通过 PBKDF2 哈希与 JWT 机制提供了可靠的认证基础。建议在生产环境中补充速率限制与 HTTPS 等安全措施,并持续监控与优化登录流程的性能与稳定性。