后端权限(用户可以访问哪些接口,有后台管理可配置)
账号->角色->权限点(具体可访问接口)
不同角色配置不同可访问权限点;账号选择角色,可选择多个角色
前端权限
- 路由鉴权
在全局守卫中,根据token、以及用户信息,编写登录前后路由跳转和访问的逻辑
router.beforeEach(async (to, from, next) => {
document.title = to.meta.title
// 获取token
let token = userStore.token
// 获取用户信息
let username = userStore.username
// 第一层判断是否有token,第二层判断跳转的是登录路由还是其他路由,仅在有token时第三层判断是否有用户信息
if(token) {// 用户登录的情况
if(to.path === '/login') {// 不能访问login,指向首页
next({path: '/'})
}else {// 其余路由放行
if(username){// 如果有用户信息,直接放行
next()
}else{// 如果没有用户信息,就在守卫里发请求获取用户信息,在放行
try{
await userStore.userInfo()
// 刷新的时候如果是异步路由,有可能获取到用户信息,异步路由还没有加载完毕,出现空白,next({...to})可以解决
next({...to})
}catch(err){// token过期,获取不到用户信息,或者手动修改本地token
await userStore.userlogout();//发送退出登录的请求
next({path: '/login',query:{redirect: to.path}})
}
}
}
}else {// 用户未登录的情况
if(to.path === '/login'){// 如果访问的是登录路由,直接放行
next()
}else {// 如果不是登录路由,重新指向登录路由,并将将要去的路由作为参数存起来
next({path:'login',query:{redirect: to.path}})
}
}
})
- 菜单权限
页面左侧菜单的展示,依赖用户数据中的异步路由信息,有后台管理可配置
1、将所有的异步路由asyncRoute和从用户数据中获取的路由数组res.data.routes进行对比,过滤出将要展示的异步路由
2、动态添加异步路由
3、深拷贝asyncRoute来使用
// store/user.js
import {constantRoute, asyncRoute, anyRoute} from '@/router/routes'
function filterAsyncRoute(asyncRoute, routes) {
return asyncRoute.filter(item => {
if(routes.includes(item.name)) {
if(item.children && item.children.length > 0) {
item.children = filterAsyncRoute(item.children, routes)
}
return true
}
})
}
export default const userStore = defineStore('User', {
state: () => {
return {}
},
action: {
async userinfo(){
let result = await reqUserInfo()
if(result.code === 200){
let userAsyncRoutes = filterAsyncRoute(cloneDeep(asyncRoute), result.data.routes)
[...userAsyncRoutes, anyRoute].forEach(route => {
router.addRoute(route)
})
}
}
}
})
- 按钮权限
页面中按钮的展示,依赖用户数据中的可访问按钮权限信息,有后台管理可配置
import pinia from '@/store'
import useUserStore from '@/stor/modules/user'
import { createApp } from 'vue';
let {buttons} = useUserStore(pinia)
app.diretive('premision', {
mouted(el,options){
if(!buttons.inclues(options.value)) {
el.parentNode.removeChild(el)
}
}
})