Login and Routing Permissions (Promoted)
Let’s post the flow chart I’ve been drawing for almost an hour. It’s a little ugly, but it’s still good to see
Let’s talk about it in detail
The login. The vue web page
// Click the login button
<el-button @click.prevent="handleLogin">Login</el-button>
let loginReq = () = > {
store
// See store/modules/user.js below for details
.dispatch('user/login', formInline)
.then(() = > {
State. redirect-> Record the last redirect to the login page path * state.otherQuery-> Record the last redirect to the login page parameter. Redirect and otherQuery are empty * */
proxy.$router.push({ path: state.redirect || '/'.query: state.otherQuery })
})
.catch((res) = > {
// An error message is displayed
tipMessage.value = res.msg
})
}
Copy the code
store/modules/user.js
//dispatch('user/login', formInline)
// Use localStorage to store tokens
import { setToken, removeToken } from '@/utils/auth login({ commit }, data) { return new Promise((resolve, Reject) => {// Send the login request loginReq(data). Then ((res) => {if (res.code === 20000) {// Store the token in localStorage setToken(res.data? .jwtToken) resolve() } else { reject(res) } }) .catch((error) => { reject(error) }) }) },Copy the code
permission.js
// Page whitelist
const whiteList = ['/login']
router.beforeEach(async (to, from, next) => {
// Start page animation
if (settings.isNeedNprogress) NProgress.start()
// Set the page tital
document.title = getPageTitle(to.meta.title)
// Whether login is required: Yes -> obtain the token, no -> set a temporary token
let hasToken = settings.isNeedLogin ? getToken() : 'temp_token'
if (hasToken) {
if (to.path === '/login') {
// If you go to the login page with a token, set the login home page
next({ path: '/'})}else {
// Whether user information has been obtained
let isGetUserInfo = store.state.permission.isGetUserInfo
if (isGetUserInfo) {
// If the user information is obtained, the dynamic route is displayed. After the user information is set, the page is directly allowed
next()
} else {
// No user information has been obtained. User information setting and dynamic route filtering process
try {
let accessRoutes = []
/* Whether to log in: Yes: the user information is set, and dynamic route filtering is performed. No: dynamic routes are not filtered. * */
if (settings.isNeedLogin) {
// Request user information
const { roles } = await store.dispatch('user/getInfo')
/ / filter dynamic routing, permission/generateRoutes process in detail below
accessRoutes = await store.dispatch('permission/generateRoutes', roles)
// Static routes and filtered dynamic routes are set to vuex and displayed in the sideBar
store.commit('permission/M_routes', accessRoutes)
} else {
accessRoutes = asyncRoutes
store.commit('permission/M_routes', accessRoutes)
}
// Set accessRoutes to vue-router
accessRoutes.forEach((route) = > {
router.addRoute(route)
})
Set isGetUserInfo to true
store.commit('permission/M_isGetUserInfo'.true)
// replace: true, clear the browser historynext({ ... to,replace: true})}catch (err) {
// If an error occurs, reset the state and redirect to the login page
await store.dispatch('user/resetToken')
next(`/login? redirect=${to.path}`)
if (settings.isNeedNprogress) NProgress.done()
}
}
}
} else {
// The whitelist page is directly allowed. Otherwise, you are redirected to the login page
if(whiteList.indexOf(to.path) ! = = -1) {
next()
} else {
next(`/login? redirect=${to.path}`)
if (settings.isNeedNprogress) NProgress.done()
}
}
})
Copy the code
store/modules/permission.js
//store.dispatch('permission/generateRoutes', roles)
generateRoutes({ commit }, roles) {
return new Promise(async (resolve) => {
let accessedRoutes
// Determine how to filter dynamic routes, roles or codeArr
if (settings.permissionMode === 'roles') {
if (roles.includes('admin')) {
// If the role is admin, the highest permission is not filtered
accessedRoutes = asyncRoutes || []
} else {
// call filterAsyncRoutes to filterAsyncRoutes based on roles
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
} else {
// Get codeArr data, if not set to [1]
let codeArr = localStorage.getItem('codeArr')
if (codeArr) {
codeArr = JSON.parse(codeArr)
} else {
localStorage.setItem('codeArr'.JSON.stringify([1]))
codeArr = localStorage.getItem('codeArr')}// Execute filterRouterByCodeArr to filter asyncRoutes based on codeArr
accessedRoutes = await filterRouterByCodeArr(codeArr, asyncRoutes)
}
// Dynamic route filtering is complete and configured to vuEX for subsequent use
commit('M_routes', accessedRoutes)
// Returns the filtered dynamic route to permission.js
resolve(accessedRoutes)
})
}
/** * Filter dynamic routes by role *@param Routes Dynamic routes *@param Roles Array of roles passed in */
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach((route) = > {
consttmp = { ... route }if (hasPermission(roles, tmp)) {
if (tmp.children) {
// Recursively call the current method to filter children
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
Roles is included in route.meta. Roles, true if so
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some((role) = > route.meta.roles.includes(role))
} else {
return true}}/** * Filter dynamic routes through codeArr@param codeArr
* @param asyncRoutes* /
function filterRouterByCodeArr(codeArr, asyncRoutes) {
return new Promise((resolve) = > {
let filterRouter = []
asyncRoutes.forEach(async (routeItem) => {
if (hasCodePermission(codeArr, routeItem)) {
if (routeItem.children) {
routeItem.children = await filterRouterByCodeArr(codeArr, routeItem.children)
}
filterRouter.push(routeItem)
}
})
resolve(filterRouter)
})
}
function hasCodePermission(codeArr, routeItem) {
if (routeItem.meta && routeItem.meta.code) {
// If hidden is true, this route is not filtered
return codeArr.includes(routeItem.meta.code) || routeItem.hidden
} else {
return true}}Copy the code
In general, dynamic filtering dynamic routing asyncRoutes by role or codeArr. After obtaining the dynamic route, call vue-router
Router. addRoute(route) Sets a route and mounts it to a real router