# 一.权限认证(权限管理)

前言

前端设置权限可以对用户访问系统进行控制,按照安全规则、安全策略控制用户只能访问被授权的资源,一般包含 认证授权 两部分

  • 1.基于角色的访问控制
  • 2.基于资源的访问控制

# 1.路由权限

  • 首先在路由定义页面定义路由相关信息,meta 中的字段控制相关的权限
    • requiresAuth: 是否登录
    • role:用户是那种角色才能进入
{
  path: '/user',
  name: '用户',
  component: User,
  meta: { requiresAuth: true, role:['1'] }
}
1
2
3
4
5
6

根据后端返回的数据,格式化树结构,并提取用户权限

// 默认设置没有获取过权限
export default new Vuex.Store({
  state: {
    hasPermission: false,
  },
  mutations: {
    setPermission(state) {
      state.hasPermission = true;
    },
  },
});
1
2
3
4
5
6
7
8
9
10
11

路由进入前执行相关逻辑,调用接口,返回的参数可以拿到用户的相关信息,来判断相关路由是否显示

router.beforeEach(async (to, from, next) => {
  if (!store.state.hasPermission) {
    // 获取最新路由列表
    let newRoutes = await store.dispatch("getRouteList");
    router.addRoutes(newRoutes); // 增加新路由
    next({ ...to, replace: true });
  } else {
    next(); // 获取过就不需要再次获取了
  }
});
1
2
3
4
5
6
7
8
9
10

获取相关需要数据

import {authRoutes} from './router'
const getRoutes = auth => {
  const filter = (authRoutes)=>{
    return authRoutes.filter(route=>{
      // 包含权限
      if(auth.includes(route.name)){
        if(route.children){
          route.children = filter(route.children);
        }
        return true;
      }
    })
  }
  return filter(authRoutes);
};

// 获取需要添加的路由列表
async getRouteList({ dispatch, commit }) {
    let auths = await axios.get("/common-node/api/roleAuth");
    let menuList = auths.data.menuList;
    let { menu, auth } = getMenListAndAuth(menuList);
    commit("setMenu", menu); // 将菜单数据保存起来
    commit("setPermission"); // 权限获取完毕
    // 通过auth查找需要添加的路由
    return getRoutes(auth);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 2.按钮权限

权限数据

state: {
    hasPermission: false,
    menu: [], // 菜单权限
    btnPermission:{ // 按钮权限
        edit:false,
        add:true
    }
}
1
2
3
4
5
6
7
8

全局自定义指令

directives: {
  perm: {
   inserted(el, bindings, vnode) {
     let value = bindings.value;
     // 在vuex中查看是否有按钮权限
     let flag = vnode.context.$store.state.btnPermission[value];
     // 如果没有全选则将按钮删除即可
     !flag && el.parentNode.removeChild(el);
   }
  }
 }
1
2
3
4
5
6
7
8
9
10
11

使用

<el-button v-perm="'edit'">编辑</el-button>
<el-button v-perm="'add'">添加</el-button>
1
2

# 3.用户授权