# Nova Admin 登录鉴权系统文档 ## 概述 Nova Admin 采用基于 JWT Token 的登录鉴权机制,通过 Pinia Store 管理认证状态,结合路由守卫实现完整的身份验证和访问控制。 ## 🏗️ 架构设计 ### 核心组件 1. **认证状态管理** (`src/store/auth.ts`) 2. **路由守卫** (`src/router/guard.ts`) 3. **登录页面** (`src/views/login/`) 4. **API 接口** (`src/service/api/login.ts`) 5. **本地存储工具** (`src/utils/storage.ts`) ## 🔐 认证流程 ### 1. 登录流程 ```mermaid sequenceDiagram participant U as 用户 participant L as 登录页面 participant A as AuthStore participant API as 后端API participant R as RouteStore participant Router as 路由系统 U->>L: 输入用户名密码 L->>A: authStore.login(username, password) A->>API: fetchLogin(credentials) API-->>A: 返回用户信息和Token A->>A: 保存Token和用户信息到localStorage A->>R: routeStore.initAuthRoute() R->>R: 初始化用户路由和菜单 A->>Router: 重定向到首页或redirect页面 ``` ### 2. 登出流程 ```mermaid sequenceDiagram participant U as 用户 participant A as AuthStore participant R as RouteStore participant T as TabStore participant Router as 路由系统 U->>A: authStore.logout() A->>A: 清除本地存储(Token, userInfo) A->>R: routeStore.resetRouteStore() A->>T: tabStore.clearAllTabs() A->>A: 重置Store状态 A->>Router: 重定向到登录页 ``` ## 📁 文件结构详解 ### AuthStore (`src/store/auth.ts`) 负责管理用户认证状态和相关操作: #### 状态管理 ```typescript interface AuthStatus { userInfo: Api.Login.Info | null // 用户信息 token: string // 访问令牌 } ``` #### 核心方法 - **`login(userName, password)`**: 执行登录操作 - **`logout()`**: 执行登出操作 - **`handleLoginInfo(data)`**: 处理登录成功后的数据 - **`clearAuthStorage()`**: 清除本地认证存储 #### 计算属性 - **`isLogin`**: 基于 token 判断用户是否已登录 ### 登录页面组件 #### 主要文件 - `src/views/login/index.vue` - 登录页面容器 - `src/views/login/components/Login/index.vue` - 登录表单组件 - `src/views/login/components/Register/index.vue` - 注册组件 - `src/views/login/components/ResetPwd/index.vue` - 重置密码组件 #### 登录表单特性 - 表单验证(用户名和密码必填) - 记住密码功能 - 加载状态提示 - 国际化支持 ### API 接口 (`src/service/api/login.ts`) #### 核心接口 ```typescript // 用户登录 fetchLogin(data: { userName: string, password: string }) // 刷新Token fetchUpdateToken(data: any) // 获取用户路由 fetchUserRoutes(params: { id: number }) ``` ## 🛡️ 数据存储 ### localStorage 存储项 | 键名 | 说明 | 数据类型 | |-----|------|---------| | `accessToken` | 访问令牌 | string | | `refreshToken` | 刷新令牌 | string | | `userInfo` | 用户信息 | Api.Login.Info | | `loginAccount` | 记住的登录账号 | {account: string, pwd: string} | ### 用户信息结构 ```typescript interface Api.Login.Info { accessToken: string refreshToken: string id: number userName: string role: Entity.RoleType[] // 用户角色数组 // ... 其他用户信息 } ``` ## 🔒 安全机制 ### Token 管理 1. **双Token机制** - `accessToken`: 用于API请求认证 - `refreshToken`: 用于刷新访问令牌 2. **Token 存储** - 使用 localStorage 持久化存储 - 页面刷新后自动恢复登录状态 3. **Token 验证** - 路由守卫检查 Token 有效性 - API 请求自动携带 Token ### 密码安全 1. **前端验证** - 必填验证 - 格式验证(可扩展) 2. **后端安全** - 密码加密存储(由后端实现) - 登录失败次数限制(由后端实现) ## 🚦 路由保护 ### 认证检查 路由守卫在 `beforeEach` 钩子中执行认证检查: ```typescript // 判断有无TOKEN,登录鉴权 const isLogin = Boolean(local.get('accessToken')) if (to.meta.requiresAuth === true && !isLogin) { const redirect = to.name === '404' ? undefined : to.fullPath next({ path: '/login', query: { redirect } }) return } ``` ### 重定向机制 1. **未登录访问受保护路由**: 重定向到登录页,并保存原始路由 2. **登录成功**: 重定向到原始路由或默认首页 3. **已登录访问登录页**: 重定向到首页 ## 🛠️ 开发指南 ### 添加新的认证检查 1. **在路由元信息中设置认证要求**: ```typescript { path: '/protected', meta: { requiresAuth: true // 需要登录 } } ``` 2. **在组件中检查登录状态**: ```typescript import { useAuthStore } from '@/store' const authStore = useAuthStore() if (!authStore.isLogin) { // 处理未登录状态 } ``` ### 自定义登录逻辑 可以通过扩展 `AuthStore` 的 `login` 方法来实现自定义登录逻辑: ```typescript // 扩展登录验证 async login(userName: string, password: string, captcha?: string) { try { // 添加验证码验证 if (this.needCaptcha && !captcha) { throw new Error('需要验证码') } const { isSuccess, data } = await fetchLogin({ userName, password, captcha }) if (!isSuccess) return await this.handleLoginInfo(data) } catch (e) { console.warn('[Login Error]:', e) } } ``` ## 🔧 配置项 ### 环境变量 - `VITE_ROUTE_LOAD_MODE`: 路由加载模式(static/dynamic) - `VITE_HOME_PATH`: 登录成功后的默认首页路径 ### 默认配置 ```typescript // 默认登录账号(开发环境) const formValue = ref({ account: 'admin', pwd: '123456', }) ``` ## 🚨 常见问题 ### 1. Token 过期处理 系统会在请求拦截器中自动处理 Token 过期: - 检测到 Token 过期 - 自动调用刷新 Token 接口 - 重新发送原始请求 ### 2. 路由初始化时机 确保在路由守卫中正确初始化路由: ```typescript if (!routeStore.isInitAuthRoute) { await routeStore.initAuthRoute() // 处理 404 重新导航 if (to.name === '404') { next({ path: to.fullPath, replace: true }) return } } ``` ### 3. 登录状态丢失 检查以下几点: - localStorage 是否被清除 - Token 是否过期 - 网络请求是否正常 ## 📚 相关文档 - [权限系统文档](./权限管理系统文档) - [路由系统文档](./路由管理系统文档) - [整体架构文档](./整体架构文档)