mirror of
https://github.com/pure-admin/pure-admin-thin.git
synced 2025-04-25 16:07:19 +08:00
feat: 实现登录登出的逻辑
This commit is contained in:
parent
8f46526cc0
commit
a021e7f9d5
@ -10,6 +10,8 @@ export type CaptchaDTO = {
|
|||||||
export type ConfigDTO = {
|
export type ConfigDTO = {
|
||||||
/** 验证码开关 */
|
/** 验证码开关 */
|
||||||
isCaptchaOn: boolean;
|
isCaptchaOn: boolean;
|
||||||
|
/** 系统字典配置(下拉选项之类的) */
|
||||||
|
dictTypes: Map<String, Array<DictionaryData>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LoginByPasswordDTO = {
|
export type LoginByPasswordDTO = {
|
||||||
@ -23,16 +25,26 @@ export type LoginByPasswordDTO = {
|
|||||||
captchaCodeKey: string;
|
captchaCodeKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RefreshTokenResult = {
|
/**
|
||||||
success: boolean;
|
* 后端token实现
|
||||||
data: {
|
*/
|
||||||
/** `token` */
|
export type TokenDTO = {
|
||||||
accessToken: string;
|
/** token */
|
||||||
/** 用于调用刷新`accessToken`的接口时所需的`token` */
|
token: string;
|
||||||
refreshToken: string;
|
/** 当前登录的用户 */
|
||||||
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */
|
currentUser: CurrentLoginUserDTO;
|
||||||
expires: Date;
|
};
|
||||||
};
|
|
||||||
|
export type CurrentLoginUserDTO = {
|
||||||
|
userInfo: any;
|
||||||
|
roleKey: string;
|
||||||
|
permissions: Set<string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DictionaryData = {
|
||||||
|
label: string;
|
||||||
|
value: Number;
|
||||||
|
cssTag: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 获取系统配置接口 */
|
/** 获取系统配置接口 */
|
||||||
@ -47,10 +59,5 @@ export const getCaptchaCode = () => {
|
|||||||
|
|
||||||
/** 登录接口 */
|
/** 登录接口 */
|
||||||
export const loginByPassword = (data: LoginByPasswordDTO) => {
|
export const loginByPassword = (data: LoginByPasswordDTO) => {
|
||||||
return http.request<ResponseData<any>>("post", "/login", { data });
|
return http.request<ResponseData<TokenDTO>>("post", "/login", { data });
|
||||||
};
|
|
||||||
|
|
||||||
/** 刷新token */
|
|
||||||
export const refreshTokenApi = (data?: object) => {
|
|
||||||
return http.request<RefreshTokenResult>("post", "/refreshToken", { data });
|
|
||||||
};
|
};
|
||||||
|
@ -32,8 +32,3 @@ export type RefreshTokenResult = {
|
|||||||
export const getLogin = (data?: object) => {
|
export const getLogin = (data?: object) => {
|
||||||
return http.request<UserResult>("post", "/login", { data });
|
return http.request<UserResult>("post", "/login", { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 刷新token */
|
|
||||||
export const refreshTokenApi = (data?: object) => {
|
|
||||||
return http.request<RefreshTokenResult>("post", "/refreshToken", { data });
|
|
||||||
};
|
|
||||||
|
@ -5,12 +5,15 @@ import { routeMetaType } from "../types";
|
|||||||
import userAvatar from "@/assets/user.jpg";
|
import userAvatar from "@/assets/user.jpg";
|
||||||
import { getTopMenu } from "@/router/utils";
|
import { getTopMenu } from "@/router/utils";
|
||||||
import { useGlobal } from "@pureadmin/utils";
|
import { useGlobal } from "@pureadmin/utils";
|
||||||
|
import { routerArrays } from "@/layout/types";
|
||||||
import { useRouter, useRoute } from "vue-router";
|
import { useRouter, useRoute } from "vue-router";
|
||||||
import { router, remainingPaths } from "@/router";
|
import { router, remainingPaths, resetRouter } from "@/router";
|
||||||
import { computed, type CSSProperties } from "vue";
|
import { computed, type CSSProperties } from "vue";
|
||||||
import { useAppStoreHook } from "@/store/modules/app";
|
import { useAppStoreHook } from "@/store/modules/app";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
|
import { removeToken } from "@/utils/auth";
|
||||||
|
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||||
|
|
||||||
const errorInfo = "当前路由配置不正确,请检查配置";
|
const errorInfo = "当前路由配置不正确,请检查配置";
|
||||||
|
|
||||||
@ -67,7 +70,12 @@ export function useNav() {
|
|||||||
|
|
||||||
/** 退出登录 */
|
/** 退出登录 */
|
||||||
function logout() {
|
function logout() {
|
||||||
useUserStoreHook().logOut();
|
useUserStoreHook().SET_USERNAME("");
|
||||||
|
useUserStoreHook().SET_ROLES([]);
|
||||||
|
removeToken();
|
||||||
|
useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
|
||||||
|
resetRouter();
|
||||||
|
router.push("/login");
|
||||||
}
|
}
|
||||||
|
|
||||||
function backTopMenu() {
|
function backTopMenu() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// import "@/utils/sso";
|
// import "@/utils/sso";
|
||||||
import { getConfig } from "@/config";
|
import { getConfig } from "@/config";
|
||||||
import NProgress from "@/utils/progress";
|
import NProgress from "@/utils/progress";
|
||||||
import { sessionKey, type DataInfo } from "@/utils/auth";
|
import { sessionKey } from "@/utils/auth";
|
||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
import {
|
import {
|
||||||
@ -25,6 +25,7 @@ import { buildHierarchyTree } from "@/utils/tree";
|
|||||||
import { isUrl, openLink, storageSession, isAllEmpty } from "@pureadmin/utils";
|
import { isUrl, openLink, storageSession, isAllEmpty } from "@pureadmin/utils";
|
||||||
|
|
||||||
import remainingRouter from "./modules/remaining";
|
import remainingRouter from "./modules/remaining";
|
||||||
|
import { TokenDTO } from "@/api/common";
|
||||||
|
|
||||||
/** 自动导入全部静态路由,无需再手动引入!匹配 src/router/modules 目录(任何嵌套级别)中具有 .ts 扩展名的所有文件,除了 remaining.ts 文件
|
/** 自动导入全部静态路由,无需再手动引入!匹配 src/router/modules 目录(任何嵌套级别)中具有 .ts 扩展名的所有文件,除了 remaining.ts 文件
|
||||||
* 如何匹配所有文件请看:https://github.com/mrmlnc/fast-glob#basic-syntax
|
* 如何匹配所有文件请看:https://github.com/mrmlnc/fast-glob#basic-syntax
|
||||||
@ -108,7 +109,7 @@ router.beforeEach((to: ToRouteType, _from, next) => {
|
|||||||
handleAliveRoute(to);
|
handleAliveRoute(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const userInfo = storageSession().getItem<DataInfo<number>>(sessionKey);
|
const userInfo = storageSession().getItem<TokenDTO>(sessionKey)?.currentUser;
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
const externalLink = isUrl(to?.name as string);
|
const externalLink = isUrl(to?.name as string);
|
||||||
if (!externalLink) {
|
if (!externalLink) {
|
||||||
@ -125,7 +126,7 @@ router.beforeEach((to: ToRouteType, _from, next) => {
|
|||||||
}
|
}
|
||||||
if (userInfo) {
|
if (userInfo) {
|
||||||
// 无权限跳转403页面
|
// 无权限跳转403页面
|
||||||
if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.roles)) {
|
if (to.meta?.roles && !isOneOfArray(to.meta?.roles, [userInfo.roleKey])) {
|
||||||
next({ path: "/error/403" });
|
next({ path: "/error/403" });
|
||||||
}
|
}
|
||||||
// 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
|
// 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
|
||||||
|
@ -19,7 +19,7 @@ import {
|
|||||||
import { getConfig } from "@/config";
|
import { getConfig } from "@/config";
|
||||||
import { menuType } from "@/layout/types";
|
import { menuType } from "@/layout/types";
|
||||||
import { buildHierarchyTree } from "@/utils/tree";
|
import { buildHierarchyTree } from "@/utils/tree";
|
||||||
import { sessionKey, type DataInfo } from "@/utils/auth";
|
import { sessionKey } from "@/utils/auth";
|
||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
const IFrame = () => import("@/layout/frameView.vue");
|
const IFrame = () => import("@/layout/frameView.vue");
|
||||||
@ -28,6 +28,7 @@ const modulesRoutes = import.meta.glob("/src/views/**/*.{vue,tsx}");
|
|||||||
|
|
||||||
// 动态路由
|
// 动态路由
|
||||||
import { getAsyncRoutes } from "@/api/routes";
|
import { getAsyncRoutes } from "@/api/routes";
|
||||||
|
import { TokenDTO } from "@/api/common";
|
||||||
|
|
||||||
function handRank(routeInfo: any) {
|
function handRank(routeInfo: any) {
|
||||||
const { name, path, parentId, meta } = routeInfo;
|
const { name, path, parentId, meta } = routeInfo;
|
||||||
@ -83,8 +84,9 @@ function isOneOfArray(a: Array<string>, b: Array<string>) {
|
|||||||
|
|
||||||
/** 从sessionStorage里取出当前登陆用户的角色roles,过滤无权限的菜单 */
|
/** 从sessionStorage里取出当前登陆用户的角色roles,过滤无权限的菜单 */
|
||||||
function filterNoPermissionTree(data: RouteComponent[]) {
|
function filterNoPermissionTree(data: RouteComponent[]) {
|
||||||
const currentRoles =
|
const roleKey =
|
||||||
storageSession().getItem<DataInfo<number>>(sessionKey)?.roles ?? [];
|
storageSession().getItem<TokenDTO>(sessionKey).currentUser.roleKey;
|
||||||
|
const currentRoles = roleKey ? [roleKey] : [];
|
||||||
const newTree = cloneDeep(data).filter((v: any) =>
|
const newTree = cloneDeep(data).filter((v: any) =>
|
||||||
isOneOfArray(v.meta?.roles, currentRoles)
|
isOneOfArray(v.meta?.roles, currentRoles)
|
||||||
);
|
);
|
||||||
|
@ -4,19 +4,21 @@ import { userType } from "./types";
|
|||||||
import { routerArrays } from "@/layout/types";
|
import { routerArrays } from "@/layout/types";
|
||||||
import { router, resetRouter } from "@/router";
|
import { router, resetRouter } from "@/router";
|
||||||
import { storageSession } from "@pureadmin/utils";
|
import { storageSession } from "@pureadmin/utils";
|
||||||
import { getLogin, refreshTokenApi } from "@/api/user";
|
|
||||||
import { UserResult, RefreshTokenResult } from "@/api/user";
|
|
||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||||
import { type DataInfo, setToken, removeToken, sessionKey } from "@/utils/auth";
|
import { type removeToken, sessionKey } from "@/utils/auth";
|
||||||
|
import { TokenDTO } from "@/api/common";
|
||||||
|
|
||||||
export const useUserStore = defineStore({
|
export const useUserStore = defineStore({
|
||||||
id: "ag-user",
|
id: "ag-user",
|
||||||
state: (): userType => ({
|
state: (): userType => ({
|
||||||
// 用户名
|
// 用户名
|
||||||
username:
|
username:
|
||||||
storageSession().getItem<DataInfo<number>>(sessionKey)?.username ?? "",
|
storageSession().getItem<TokenDTO>(sessionKey)?.currentUser.userInfo
|
||||||
|
.username ?? "",
|
||||||
// 页面级别权限
|
// 页面级别权限
|
||||||
roles: storageSession().getItem<DataInfo<number>>(sessionKey)?.roles ?? []
|
roles: storageSession().getItem<TokenDTO>(sessionKey)?.currentUser.roleKey
|
||||||
|
? [storageSession().getItem<TokenDTO>(sessionKey)?.currentUser.roleKey]
|
||||||
|
: []
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
/** 存储用户名 */
|
/** 存储用户名 */
|
||||||
@ -27,21 +29,6 @@ export const useUserStore = defineStore({
|
|||||||
SET_ROLES(roles: Array<string>) {
|
SET_ROLES(roles: Array<string>) {
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
},
|
},
|
||||||
/** 登入 */
|
|
||||||
async loginByUsername(data) {
|
|
||||||
return new Promise<UserResult>((resolve, reject) => {
|
|
||||||
getLogin(data)
|
|
||||||
.then(data => {
|
|
||||||
if (data) {
|
|
||||||
setToken(data.data);
|
|
||||||
resolve(data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 前端登出(不调用接口) */
|
/** 前端登出(不调用接口) */
|
||||||
logOut() {
|
logOut() {
|
||||||
this.username = "";
|
this.username = "";
|
||||||
@ -50,21 +37,6 @@ export const useUserStore = defineStore({
|
|||||||
useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
|
useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
|
||||||
resetRouter();
|
resetRouter();
|
||||||
router.push("/login");
|
router.push("/login");
|
||||||
},
|
|
||||||
/** 刷新`token` */
|
|
||||||
async handRefreshToken(data) {
|
|
||||||
return new Promise<RefreshTokenResult>((resolve, reject) => {
|
|
||||||
refreshTokenApi(data)
|
|
||||||
.then(data => {
|
|
||||||
if (data) {
|
|
||||||
setToken(data.data);
|
|
||||||
resolve(data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,11 @@ import Cookies from "js-cookie";
|
|||||||
import { storageSession } from "@pureadmin/utils";
|
import { storageSession } from "@pureadmin/utils";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
import { aesEncrypt, aesDecrypt } from "@/utils/crypt";
|
import { aesEncrypt, aesDecrypt } from "@/utils/crypt";
|
||||||
|
import { TokenDTO } from "@/api/common";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原版前端token实现
|
||||||
|
*/
|
||||||
export interface DataInfo<T> {
|
export interface DataInfo<T> {
|
||||||
/** token */
|
/** token */
|
||||||
accessToken: string;
|
accessToken: string;
|
||||||
@ -22,52 +26,23 @@ export const isRememberMeKey = "ag-is-remember-me";
|
|||||||
export const passwordKey = "ag-password";
|
export const passwordKey = "ag-password";
|
||||||
|
|
||||||
/** 获取`token` */
|
/** 获取`token` */
|
||||||
export function getToken(): DataInfo<number> {
|
export function getToken(): TokenDTO {
|
||||||
// 此处与`TokenKey`相同,此写法解决初始化时`Cookies`中不存在`TokenKey`报错
|
// 此处与`TokenKey`相同,此写法解决初始化时`Cookies`中不存在`TokenKey`报错
|
||||||
return Cookies.get(tokenKey)
|
return Cookies.get(tokenKey)
|
||||||
? JSON.parse(Cookies.get(tokenKey))
|
? JSON.parse(Cookies.get(tokenKey))
|
||||||
: storageSession().getItem(sessionKey);
|
: storageSession().getItem<TokenDTO>(sessionKey).token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 设置`token`以及一些必要信息并采用无感刷新`token`方案
|
* 后端处理token
|
||||||
* 无感刷新:后端返回`accessToken`(访问接口使用的`token`)、`refreshToken`(用于调用刷新`accessToken`的接口时所需的`token`,`refreshToken`的过期时间(比如30天)应大于`accessToken`的过期时间(比如2小时))、`expires`(`accessToken`的过期时间)
|
|
||||||
* 将`accessToken`、`expires`这两条信息放在key值为authorized-token的cookie里(过期自动销毁)
|
|
||||||
* 将`username`、`roles`、`refreshToken`、`expires`这四条信息放在key值为`user-info`的sessionStorage里(浏览器关闭自动销毁)
|
|
||||||
*/
|
*/
|
||||||
export function setToken(data: DataInfo<Date>) {
|
export function setTokenFromBackend(data: TokenDTO): void {
|
||||||
let expires = 0;
|
const cookieString = JSON.stringify(data);
|
||||||
const { accessToken, refreshToken } = data;
|
Cookies.set(tokenKey, cookieString);
|
||||||
expires = new Date(data.expires).getTime(); // 如果后端直接设置时间戳,将此处代码改为expires = data.expires,然后把上面的DataInfo<Date>改成DataInfo<number>即可
|
|
||||||
const cookieString = JSON.stringify({ accessToken, expires });
|
|
||||||
|
|
||||||
expires > 0
|
useUserStoreHook().SET_USERNAME(data.currentUser.userInfo.username);
|
||||||
? Cookies.set(tokenKey, cookieString, {
|
useUserStoreHook().SET_ROLES([data.currentUser.roleKey]);
|
||||||
expires: (expires - Date.now()) / 86400000
|
storageSession().setItem(sessionKey, data);
|
||||||
})
|
|
||||||
: Cookies.set(tokenKey, cookieString);
|
|
||||||
|
|
||||||
function setSessionKey(username: string, roles: Array<string>) {
|
|
||||||
useUserStoreHook().SET_USERNAME(username);
|
|
||||||
useUserStoreHook().SET_ROLES(roles);
|
|
||||||
storageSession().setItem(sessionKey, {
|
|
||||||
refreshToken,
|
|
||||||
expires,
|
|
||||||
username,
|
|
||||||
roles
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.username && data.roles) {
|
|
||||||
const { username, roles } = data;
|
|
||||||
setSessionKey(username, roles);
|
|
||||||
} else {
|
|
||||||
const username =
|
|
||||||
storageSession().getItem<DataInfo<number>>(sessionKey)?.username ?? "";
|
|
||||||
const roles =
|
|
||||||
storageSession().getItem<DataInfo<number>>(sessionKey)?.roles ?? [];
|
|
||||||
setSessionKey(username, roles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除`token`以及key值为`user-info`的session信息 */
|
/** 删除`token`以及key值为`user-info`的session信息 */
|
||||||
|
@ -8,10 +8,19 @@ const publicKey =
|
|||||||
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh6HkK+rCM37FAzCHVythTc6pxvr551K07CRhdX/NjCddHAuQMOd/57R5fiIwgVNEfCsD1cIyS6A8IWj4DtJLR2t29JehPpqiFSJ4hNtDcLNxNJiYRcCQvyMQeyQIPE5Ljc35c72YwDtQAsIJChsauyLrc+E6HC3gn1JDm18HNXwIDAQAB";
|
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh6HkK+rCM37FAzCHVythTc6pxvr551K07CRhdX/NjCddHAuQMOd/57R5fiIwgVNEfCsD1cIyS6A8IWj4DtJLR2t29JehPpqiFSJ4hNtDcLNxNJiYRcCQvyMQeyQIPE5Ljc35c72YwDtQAsIJChsauyLrc+E6HC3gn1JDm18HNXwIDAQAB";
|
||||||
|
|
||||||
// 加密
|
// 加密
|
||||||
export function rsaEncrypt(txt) {
|
export function rsaEncrypt(txt): string {
|
||||||
const encryptor = new JSEncrypt();
|
const encryptor = new JSEncrypt();
|
||||||
encryptor.setPublicKey(publicKey); // 设置公钥
|
// 设置公钥
|
||||||
return encryptor.encrypt(txt); // 对数据进行加密
|
encryptor.setPublicKey(publicKey);
|
||||||
|
// 对数据进行加密
|
||||||
|
const encryptedValue = encryptor.encrypt(txt);
|
||||||
|
|
||||||
|
// Check if the encrypted value is a boolean
|
||||||
|
if (typeof encryptedValue === "boolean") {
|
||||||
|
throw new Error("Encryption failed: Encrypted value returned a boolean");
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const aesKey = "agileboot1234567";
|
const aesKey = "agileboot1234567";
|
||||||
|
@ -12,7 +12,6 @@ import {
|
|||||||
import { stringify } from "qs";
|
import { stringify } from "qs";
|
||||||
import NProgress from "../progress";
|
import NProgress from "../progress";
|
||||||
import { getToken, formatToken } from "@/utils/auth";
|
import { getToken, formatToken } from "@/utils/auth";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
|
||||||
|
|
||||||
const { VITE_APP_BASE_API } = import.meta.env;
|
const { VITE_APP_BASE_API } = import.meta.env;
|
||||||
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
||||||
@ -76,42 +75,18 @@ class PureHttp {
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
/** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */
|
/** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */
|
||||||
const whiteList = ["/refreshToken", "/login", "/captchaImage"];
|
const whiteList = [
|
||||||
|
"/refreshToken",
|
||||||
|
"/login",
|
||||||
|
"/captchaImage",
|
||||||
|
"/getConfig"
|
||||||
|
];
|
||||||
return whiteList.some(v => config.url.indexOf(v) > -1)
|
return whiteList.some(v => config.url.indexOf(v) > -1)
|
||||||
? config
|
? config
|
||||||
: new Promise(resolve => {
|
: new Promise(resolve => {
|
||||||
const data = getToken();
|
const data = getToken();
|
||||||
|
config.headers["Authorization"] = formatToken(data.token);
|
||||||
console.log("当前token:" + data.accessToken);
|
|
||||||
if (data) {
|
|
||||||
const now = new Date().getTime();
|
|
||||||
const expired = parseInt(data.expires) - now <= 0;
|
|
||||||
if (expired) {
|
|
||||||
if (!PureHttp.isRefreshing) {
|
|
||||||
PureHttp.isRefreshing = true;
|
|
||||||
// token过期刷新
|
|
||||||
useUserStoreHook()
|
|
||||||
.handRefreshToken({ refreshToken: data.refreshToken })
|
|
||||||
.then(res => {
|
|
||||||
const token = res.data.accessToken;
|
|
||||||
config.headers["Authorization"] = formatToken(token);
|
|
||||||
PureHttp.requests.forEach(cb => cb(token));
|
|
||||||
PureHttp.requests = [];
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
PureHttp.isRefreshing = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
resolve(PureHttp.retryOriginalRequest(config));
|
|
||||||
} else {
|
|
||||||
config.headers["Authorization"] = formatToken(
|
|
||||||
data.accessToken
|
|
||||||
);
|
|
||||||
resolve(config);
|
resolve(config);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolve(config);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
|
@ -31,9 +31,7 @@ import {
|
|||||||
getIsRememberMe,
|
getIsRememberMe,
|
||||||
savePassword,
|
savePassword,
|
||||||
getPassword,
|
getPassword,
|
||||||
removePassword,
|
removePassword
|
||||||
setToken,
|
|
||||||
DataInfo
|
|
||||||
} from "@/utils/auth";
|
} from "@/utils/auth";
|
||||||
|
|
||||||
import dayIcon from "@/assets/svg/day.svg?component";
|
import dayIcon from "@/assets/svg/day.svg?component";
|
||||||
@ -41,6 +39,7 @@ import darkIcon from "@/assets/svg/dark.svg?component";
|
|||||||
import Lock from "@iconify-icons/ri/lock-fill";
|
import Lock from "@iconify-icons/ri/lock-fill";
|
||||||
import User from "@iconify-icons/ri/user-3-fill";
|
import User from "@iconify-icons/ri/user-3-fill";
|
||||||
import * as CommonAPI from "@/api/common";
|
import * as CommonAPI from "@/api/common";
|
||||||
|
import { setTokenFromBackend } from "../../utils/auth";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "Login"
|
name: "Login"
|
||||||
@ -85,12 +84,7 @@ const onLogin = async (formEl: FormInstance | undefined) => {
|
|||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
// 登录成功后 将token存储到sessionStorage中
|
// 登录成功后 将token存储到sessionStorage中
|
||||||
const tokenData: DataInfo<Number> = {
|
setTokenFromBackend(res.data);
|
||||||
accessToken: res.data.token,
|
|
||||||
expires: undefined,
|
|
||||||
refreshToken: ""
|
|
||||||
};
|
|
||||||
setToken(tokenData);
|
|
||||||
// 获取后端路由
|
// 获取后端路由
|
||||||
initRouter().then(() => {
|
initRouter().then(() => {
|
||||||
router.push(getTopMenu(true).path);
|
router.push(getTopMenu(true).path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user