【pure-admin】项目登录模块分析
项目登录模块分析
登录工作原理
1. 登录流程概述
该项目实现了一套完整的登录认证机制,主要包含以下几个核心部分:
前端登录流程:
- 用户在登录页面(
src/views/login/index.vue
)输入用户名和密码 - 点击登录按钮后调用
onLogin
函数,该函数通过useUserStoreHook().loginByUsername()
方法向服务器发送登录请求 - 登录成功后,调用
setToken
函数保存认证信息 - 初始化路由(
initRouter()
)并跳转到首页
关键代码:
const onLogin = async (formEl: FormInstance | undefined) => {// 表单验证通过后执行登录useUserStoreHook().loginByUsername({ username: ruleForm.username, password: ruleForm.password }).then(res => {if (res.success) {// 获取后端路由并跳转return initRouter().then(() => {router.push(getTopMenu(true).path);});}});
};
2. Token管理机制
项目采用了 JWT (JSON Web Token) 作为认证凭证,并实现了无感刷新 Token 的方案:
-
Token 存储:
accessToken
、expires
、refreshToken
存储在 Cookie 中(自动过期)- 用户信息(头像、用户名、角色、权限等)存储在 LocalStorage 中
-
Token 刷新机制:
- 当
accessToken
即将过期时,系统会自动调用/refresh-token
接口刷新 Token - 使用队列机制确保在刷新 Token 期间的请求能够正确重发
- 当
关键代码:
// 设置Token的核心逻辑
export function setToken(data: DataInfo<Date>) {// 计算过期时间expires = new Date(data.expires).getTime();// 保存到Cookie和LocalStorageCookies.set(TokenKey, cookieString, { expires: (expires - Date.now()) / 86400000 });storageLocal().setItem(userKey, { refreshToken, expires, ...userInfo });
}
3. 单点登录实现
项目实现了简版前端单点登录(SSO)功能:
- 通过 URL 参数传递认证信息(username、roles、accessToken)
- 检测到 URL 中包含完整的认证参数时,判定为单点登录请求
- 清空旧信息并保存新信息,然后重定向到正确页面
关键代码:
// 判断是否为单点登录并处理
if (sso.length === mustLength) {// 判定为单点登录// 清空本地旧信息removeToken();// 保存新信息到本地setToken(params);// 重定向到正确页面window.location.replace(newUrl);
}
与后端对接方式
1. API 接口设计
项目通过 /src/api/user.ts
定义了与后端交互的用户相关接口:
- 登录接口:
POST /login
- 接收用户名密码,返回用户信息和 Token - 刷新 Token 接口:
POST /refresh-token
- 用于刷新即将过期的 Token - 个人信息接口:
GET /mine
- 获取当前登录用户的详细信息
接口数据结构:
// 登录接口返回数据结构
export type UserResult = {success: boolean;data: {avatar: string;username: string;nickname: string;roles: Array<string>;permissions: Array<string>;accessToken: string;refreshToken: string;expires: Date;};
};
2. HTTP 请求拦截器
项目使用 Axios 进行 HTTP 请求,并通过拦截器实现了以下功能:
-
请求拦截:
- 自动添加
Authorization
头部信息 - 检测 Token 是否过期,自动刷新
- 实现请求白名单,避免死循环
- 自动添加
-
响应拦截:
- 统一处理响应数据
- 错误处理和进度条管理
关键代码:
// 请求拦截器中的Token处理逻辑
const whiteList = ["/refresh-token", "/login"];
return whiteList.some(url => config.url.endsWith(url))? config: new Promise(resolve => {const data = getToken();if (data) {// 检查Token是否过期并刷新const expired = parseInt(data.expires) - now <= 0;if (expired) {// 执行Token刷新逻辑}config.headers["Authorization"] = formatToken(data.accessToken);}resolve(config);});
3. Store 状态管理
项目使用 Pinia 管理用户状态,通过 useUserStore
封装了用户相关的操作:
- 登录(
loginByUsername
) - 登出(
logOut
) - 刷新 Token(
handRefreshToken
) - 存储和获取用户信息
关键代码:
// 登录方法
async loginByUsername(data) {return new Promise<UserResult>((resolve, reject) => {getLogin(data).then(data => {if (data?.success) setToken(data.data);resolve(data);}).catch(error => {reject(error);});});
}
如何与后端对接
要与实际后端进行对接,需要注意以下几点:
- 确保接口地址正确: 根据实际后端服务地址配置请求基础路径
- 统一数据格式: 确保后端返回的数据格式与前端定义的
UserResult
等类型一致 - Token 策略匹配: 后端需要实现与前端对应的 Token 生成和刷新机制
- 权限控制: 后端需要根据用户角色和权限返回对应的路由和操作权限
- 单点登录配置: 如果需要启用单点登录,需要与认证中心协调参数传递方式
通过以上分析,可以看出该项目的登录模块设计完善,包含了常规登录、单点登录、Token 自动刷新等功能,为前后端分离架构提供了良好的安全认证机制。
ps:借助AI分析,可能有误,供参考