vue 路由守卫实现权限控制

前言

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

实现步骤

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

	this.axios
        .post(`${request.URL.LOGIN}`, {
          ...
        })
        .then(res => {
        	...
        	localStorage.setItem("userInfo", JSON.stringify(res.data));
			...
        })

(二)在路由配置文件中,把需要权限校验的页面增加 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 }
	    },
    ]
});

(三)增加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>

(四)在项目的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. 对页面进行权限控制前,先判断是否登录,如未登录,先跳转到登录页面,而非403页面
2. 登录后的权限信息,应缓存在localStorage中,如缓存在state中,则有可能出现用户新开一个浏览器窗口,登录凭证还在,但获取不到权限控制数据,导致判断错误

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值