• vue 路由守卫实现权限控制


    前言

    在配置有菜单权限的系统中,根据菜单显示来控制是否能访问某页面,能看得到但菜单就能点击访问,但如果直接访问页面路径,则跳出了菜单控制的范畴,所以要在每次访问页面前,对当前访问对路径进行权限校验,才能达到权限控制的目的

    实现步骤

    (一)在页面登录后,把账户权限信息缓存在localStorage中

    	this.axios
            .post(`${request.URL.LOGIN}`, {
              ...
            })
            .then(res => {
            	...
            	localStorage.setItem("userInfo", JSON.stringify(res.data));
    			...
            })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (二)在路由配置文件中,把需要权限校验的页面增加 forbidden: true

    const router = new Router({
      routes: [
    	    {
    	      path: "/",
    	      name: "Login",
    	      component: () => import("@/pages/login/login.vue"),
    	      meta: { forbidden: false }
    	    },
    	    {
    	      path: "/pharmacyList",
    	      name: "pharmacyList",
    	      component: () => import("@/pages/organizationManagement/pharmacyList.vue"),
    	      meta: { forbidden: true }
    	    },
    	    {
    	      path: "/403",
    	      name: "403",
    	      component: () => import("@/pages/403.vue"),
    	      meta: { forbidden: false }
    	    },
        ]
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    (三)增加403页面

    <template>
      <div class="forbidden">
        <div
          style="
        text-align: center;
        margin-top: 100px;
        font-size: 20px;"
        >
          403 您无权访问该页面,请联系管理员
        </div>
        <div class="btn">
          <el-button size="small" type="primary" plain @click="toHome"
            >返回首页</el-button
          >
        </div>
      </div>
    </template>
    
    <script>
    	export default {
    	  methods: {
    	    toHome() {
    	      this.$router.push("/");
    	    }
    	  }
    	};
    </script>
    
    <style scoped>
    	.forbidden {
    	  display: flex;
    	  flex-direction: column;
    	  justify-content: center;
    	}
    	.btn {
    	  display: inline-flex;
    	  margin-top: 50px;
    	  justify-content: center;
    	}
    </style>
    
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    (四)在项目的main.js文件中,写入路由守卫的逻辑
    根据项目存取的实际情况,主要思路就是判断当前访问的路径是否设置在菜单权限中
    以下为我项目中的实际判断情况,由于历史原因,是根据菜单名称进行判断,新项目如果能在权限控制时,保存菜单路径更好

    router.beforeEach((to, from, next) => {
      let userInfo = localStorage.getItem("userInfo")
        ? JSON.parse(localStorage.getItem("userInfo"))
        : {};
      // 首页无须校验是否登录
      if (!VueCookies.get("acl_t") && to.path != "/") {
        next({ path: "/", query: { noToken: true } });
      } 
      // 非首页的权限判断
      else {
        // 如果当前不是管理员,并且访问的路径没有设置forbidden=false,需要判断权限
        if (userInfo.ext != "root" && to.meta.forbidden != false) {
          // 获取用户设置的路由权限,根据项目中存取的实际情况获取
          let links = userInfo.links;
          links = links ? JSON.parse(links).home : [];
          let data = [];
          for (let l in links) {
            data.push(...links[l].children);
          }
          // 路由权限中全部可以访问的名称集合
          data = data.map(d => {
            return d.name;
          });
    
          // 路径名称查找关系
          let accountManagementData = [];
          for (let ac in accountManagement) {
            accountManagementData.push(...accountManagement[ac].children);
          }
          // 找出当前访问的页面名称
          let result = accountManagementData.find(ac => {
            return ac.path == to.name;
          });
    
          // 如果页面并没有标题,可能是详情页,不需要判断
          if (result) {
            // 如果权限里面有当前访问的名称
            if (data.includes(result.name)) {
              next();
            } else {
              next("/403");
            }
          } else {
            next();
          }
        } else {
          next();
        }
      }
    });
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    以上,根据路由守卫实现权限控制完成,其中有几点注意事项
    1. 对页面进行权限控制前,先判断是否登录,如未登录,先跳转到登录页面,而非403页面
    2. 登录后的权限信息,应缓存在localStorage中,如缓存在state中,则有可能出现用户新开一个浏览器窗口,登录凭证还在,但获取不到权限控制数据,导致判断错误

  • 相关阅读:
    hive SQL谓词下推
    第5集丨Caché 对象介绍
    使用 Alice inspector 和 Dio 进行 Flutter API 日志记录
    量化交易的相对强弱(RSI )指标计算及策略
    Dubbo学习
    PostPreSql 数据库的一些用法
    【Java I/O 流】数据输入输出流:DataInputStream 和 DataOutputStream
    css:详解BFC块级格式化上下文
    idea如何导入maven项目
    mysql执行拼接的sql语句
  • 原文地址:https://blog.csdn.net/weixin_39357177/article/details/136337340