vue.js中登录权限问题(代码)

本文详细解析了Vue.js应用中如何实现基于角色的权限管理,利用Vuex进行状态管理,结合路由守卫(beforeEach)进行权限判断与路由跳转。介绍了登录流程、token验证、动态路由生成等关键步骤。
摘要由CSDN通过智能技术生成

一、登录页面

this.$store.dispatch('LoginByEmail', this.loginForm).then(() => {
 this.$router.push({ path: '/' }); //登录成功之后重定向到首页
}).catch(err => {
 this.$message.error(err); //登录失败提示错误
});

二、vuex中异步触发的actions LoginByEmail的处理内容如下

LoginByEmail ({ commit }, userInfo) {
   const email = userInfo.email.trim()
   return new Promise((resolve, reject) => {
    loginByEmail(email, userInfo.password).then(response => {
     const data = response.data
     setToken(response.data.token)
     commit('SET_TOKEN', data.token)
     resolve()
    }).catch(error => {
     reject(error)
    })
   })
  }

三、具体代码

router.beforeEach((to, from, next) => {
 if (getToken()) { // 判断是否取到token
  if (to.path === '/login') {
   next({ path: '/' })
  } else {
   if (store.getters.roles.length === 0) { // 判断当前用户是否已获取完user_info信息
    store.dispatch('GetInfo').then(res => { // 获取user_info
     const roles = res.data.role
     store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表
      router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
      next({ ...to }) // 放行路由
     })
    }).catch(() => {
     store.dispatch('FedLogOut').then(() => {
      next({ path: '/login' })
     })
    })
   } else {
    next() // 放行该路由
   }
  }
 } else {
  if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单里的路径,继续让其访问
   next()
  } else { // 其他不在白名单里的路径全部让其重定向到登录页面!
   next('/login')
   alert('not in white list, now go to the login page')
  }
 }
})

四、具体实现

  1.router.js

        

// router.js
import Vue from 'vue';
import Router from 'vue-router';

import Login from '../views/login/';
const dashboard = resolve => require(['../views/dashboard/index'], resolve);
//使用了vue-routerd的[Lazy Loading Routes
](https://router.vuejs.org/en/advanced/lazy-loading.html)

//所有权限通用路由表 
//如首页和登录页和一些不用权限的公用页面
export const constantRouterMap = [
  { path: '/login', component: Login, hidden: true //hidden为自定义属性,侧边栏那章会纤细解释},
  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    name: '首页',
    children: [{ path: 'dashboard', component: dashboard }]
  },
]

//实例化vue的时候只挂载constantRouter
export default new Router({
  routes: constantRouterMap
});

//异步挂载的路由
//动态需要根据权限加载的路由表 
export const asyncRouterMap = [
  {
    path: '/permission',
    component: Layout,
    redirect: '/permission/index',
    name: '权限测试',
    meta: { role: ['admin','super_editor'] }, //页面需要的权限
    children: [
    { 
        path: 'index',
        component: Permission,
        name: '权限测试页',
        meta: { role: ['admin','super_editor'] }  //页面需要的权限
    }]
  },
  { path: '*', redirect: '/404', hidden: true }
];

2.main.js

// main.js
router.beforeEach((to, from, next) => {
  if (store.getters.token) { // 判断是否有token
    if (to.path === '/login') {
      next({ path: '/' });
    } else {
      if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
        store.dispatch('GetInfo').then(res => { // 拉取info
          const roles = res.data.role;
          store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表
            router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
            next(to); // hack方法 确保addRoutes已完成
          })
        }).catch(err => {
          console.log(err);
        });
      } else {
        next() //当有用户权限的时候,说明所有可访问路由已生成 如访问没权限的全面会自动进入404页面
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
      next();
    } else {
      next('/login'); // 否则全部重定向到登录页
    }
  }
});

五、登录逻辑如图

重构之前权限判断代码


上面一张图就是在使用addRoutes方法之前的权限判断,非常的繁琐,因为我是把所有的路由都挂在了上去,所有我要各种判断当前的用户是否有权限进入该页面,各种if/else的嵌套,维护起来相当的困难。但现在有了addRoutes之后就非常的方便,我只挂载了用户有权限进入的页面,没权限,路由自动帮我跳转的404,省去了不少的判断。

这里还有一个小hack的地方,就是router.addRoutes之后的next()可能会失效,因为可能next()的时候路由并没有完全add完成,好在查阅文档发现

next('/') or next({ path: '/' }): redirect to a different location. The current navigation will be aborted and a new one will be started.

这样我们就可以简单的通过next(to)巧妙的避开之前的那个问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值