fix(router): validate server session before loading routes
This commit is contained in:
1 parent
17b2ba49a8
commit
6ffdbcb3d7
7 files changed
+33
-47
No files matched your search
@@ -9,7 +9,7 @@ import axios, {
|
||||
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
|
||||
import qs from 'qs'
|
||||
import { config } from '@/config/axios/config'
|
||||
import { getTenantId, removeAuthenticated } from '@/utils/auth'
|
||||
import { getTenantId } from '@/utils/auth'
|
||||
import errorCode from './errorCode'
|
||||
|
||||
import { resetRouter } from '@/router'
|
||||
@@ -201,9 +201,8 @@ const handleAuthorized = () => {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
resetRouter() // 重置静态路由表
|
||||
removeAuthenticated()
|
||||
isRelogin.show = false
|
||||
// 干掉token后再走一次路由让它过router.beforeEach的校验
|
||||
// 重新加载后由路由守卫向服务端确认会话
|
||||
window.location.href = window.location.href
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import router from './router'
|
||||
import router, { resetRouter } from './router'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import { isRelogin } from '@/config/axios/service'
|
||||
import { isAuthenticated } from '@/utils/auth'
|
||||
import { useTitle } from '@/hooks/web/useTitle'
|
||||
import { useNProgress } from '@/hooks/web/useNProgress'
|
||||
import { usePageLoading } from '@/hooks/web/usePageLoading'
|
||||
@@ -60,42 +59,46 @@ const whiteList = [
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
start()
|
||||
loadStart()
|
||||
if (isAuthenticated()) {
|
||||
if (to.path === '/login') {
|
||||
const userStore = useUserStoreWithOut()
|
||||
if (whiteList.includes(to.path)) {
|
||||
if (to.path === '/login' && userStore.getIsSetUser) {
|
||||
next({ path: '/' })
|
||||
} else {
|
||||
// 获取所有字典
|
||||
next()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (userStore.getIsSetUser) {
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
isRelogin.show = true
|
||||
try {
|
||||
await userStore.setUserInfoAction()
|
||||
|
||||
const dictStore = useDictStoreWithOut()
|
||||
const userStore = useUserStoreWithOut()
|
||||
const permissionStore = usePermissionStoreWithOut()
|
||||
if (!dictStore.getIsSetDict) {
|
||||
await dictStore.setDictMap()
|
||||
}
|
||||
if (!userStore.getIsSetUser) {
|
||||
isRelogin.show = true
|
||||
await userStore.setUserInfoAction()
|
||||
isRelogin.show = false
|
||||
// 后端过滤菜单
|
||||
|
||||
const permissionStore = usePermissionStoreWithOut()
|
||||
await permissionStore.generateRoutes(userStore.getMenus)
|
||||
permissionStore.getAddRouters.forEach((route) => {
|
||||
router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表
|
||||
router.addRoute(route as unknown as RouteRecordRaw)
|
||||
})
|
||||
|
||||
const redirectPath = from.query.redirect || to.path
|
||||
// 修复跳转时不带参数的问题
|
||||
const redirect = decodeURIComponent(redirectPath as string)
|
||||
const { basePath, paramsObject: query } = parseURL(redirect)
|
||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect, query }
|
||||
next(nextData)
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (whiteList.indexOf(to.path) !== -1) {
|
||||
next()
|
||||
} else {
|
||||
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||
}
|
||||
const { paramsObject: query } = parseURL(redirect)
|
||||
next(to.path === redirect ? { ...to, replace: true } : { path: redirect, query })
|
||||
} catch {
|
||||
userStore.resetState()
|
||||
resetRouter()
|
||||
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`)
|
||||
} finally {
|
||||
isRelogin.show = false
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { store } from '@/store'
|
||||
import { defineStore } from 'pinia'
|
||||
import { isAuthenticated, removeAuthenticated } from '@/utils/auth'
|
||||
import { getInfo, loginOut } from '@/api/login'
|
||||
|
||||
interface UserVO {
|
||||
@@ -51,10 +50,6 @@ export const useUserStore = defineStore('admin-user', {
|
||||
},
|
||||
actions: {
|
||||
async setUserInfoAction() {
|
||||
if (!isAuthenticated()) {
|
||||
this.resetState()
|
||||
return null
|
||||
}
|
||||
const userInfo = await getInfo()
|
||||
this.permissions = userInfo.permissions
|
||||
this.roles = userInfo.roles
|
||||
@@ -72,7 +67,6 @@ export const useUserStore = defineStore('admin-user', {
|
||||
try {
|
||||
await loginOut()
|
||||
} finally {
|
||||
removeAuthenticated()
|
||||
this.resetState()
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import { useCache, CACHE_KEY } from '@/hooks/web/useCache'
|
||||
|
||||
const { wsCache } = useCache()
|
||||
const { wsCache: sessionCache } = useCache('sessionStorage')
|
||||
|
||||
wsCache.delete('ACCESS_TOKEN')
|
||||
wsCache.delete('REFRESH_TOKEN')
|
||||
wsCache.delete('user')
|
||||
wsCache.delete('roleRouters')
|
||||
|
||||
const AuthenticatedKey = 'AUTHENTICATED'
|
||||
|
||||
export const isAuthenticated = () => sessionCache.get(AuthenticatedKey) === true
|
||||
export const setAuthenticated = () => sessionCache.set(AuthenticatedKey, true)
|
||||
export const removeAuthenticated = () => sessionCache.delete(AuthenticatedKey)
|
||||
// ========== 账号相关 ==========
|
||||
|
||||
export type LoginFormType = {
|
||||
|
||||
@@ -252,7 +252,6 @@ const tryLogin = async () => {
|
||||
const state = route?.query?.state as string
|
||||
|
||||
await LoginApi.socialLogin(type, code, state)
|
||||
authUtil.setAuthenticated()
|
||||
|
||||
router.push({ path: redirect || '/' })
|
||||
} catch (err) {}
|
||||
@@ -297,7 +296,6 @@ const handleLogin = async (params) => {
|
||||
} else {
|
||||
authUtil.removeLoginForm()
|
||||
}
|
||||
authUtil.setAuthenticated()
|
||||
if (!redirect) {
|
||||
redirect = '/'
|
||||
}
|
||||
|
||||
@@ -186,7 +186,6 @@ const handleLogin = async (params) => {
|
||||
} else {
|
||||
authUtil.removeLoginForm()
|
||||
}
|
||||
authUtil.setAuthenticated()
|
||||
if (!redirect.value) {
|
||||
redirect.value = '/'
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||
|
||||
import { useIcon } from '@/hooks/web/useIcon'
|
||||
|
||||
import { setTenantId, setAuthenticated } from '@/utils/auth'
|
||||
import { setTenantId } from '@/utils/auth'
|
||||
import { usePermissionStore } from '@/store/modules/permission'
|
||||
import { getTenantIdByName, sendSmsCode, smsLogin } from '@/api/login'
|
||||
import LoginFormTitle from './LoginFormTitle.vue'
|
||||
@@ -196,7 +196,6 @@ const signIn = async () => {
|
||||
smsVO.loginSms.code = loginData.loginForm.code
|
||||
await smsLogin(smsVO.loginSms)
|
||||
.then(async () => {
|
||||
setAuthenticated()
|
||||
if (!redirect.value) {
|
||||
redirect.value = '/'
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user