登录权限管理

该篇博客详细介绍了在Vue.js项目中如何实现前端路由的权限管理,包括静态路由和动态路由的处理,以及使用Vuex进行权限状态管理。在登录时获取用户权限,并动态添加可访问的路由,确保不同角色用户只能访问其被授权的页面。同时,文章还展示了如何处理路由重定向和错误捕获,以及在路由守卫中进行权限判断。
摘要由CSDN通过智能技术生成

该篇文章主要考虑的是:一个项目可同时等前台以及后台系统

  1. 路由分为固定路由,以及动态路由
  2. 固定的路由一般我们不进行考虑,它一般在开始的时候我们就将他进行挂载了
  3. 动态路由我们需要进行接口获取时将其获取

直接上代码:

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store/index.js' // no redirect whitelist
import Admin from '@/views/admin'

const whiteList = ['/login']

Vue.use(VueRouter)

// 当报错Error: Redirected when going from "/login" to "/pandect" via a navigation guard.  该函数用来解决该问题
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (location, onResolve, onReject) {
  if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
  return originalPush.call(this, location).catch(err => err)
}

//所有权限通用路由表 
//如首页和登录页和一些不用权限的公用页面
export const constantRouterMap = [
  {
    path: '',
    redirect: '/login'
  },

  {
    path: '/',
    redirect: '/login'
  },

  {
    path: '/login',
    name: 'login',
    hidden: true,
    component: () => import('../views/login/Login.vue')
  },

  {
    path: '/user',
    name: 'user',
    hidden: true,
    component: () => import('../views/user/index.vue'),
    redirect: { name: 'home' },
    children: [
      {
        path: 'home',
        name: 'home',
        component: () => import('../views/user/home/Home.vue')
      }, {
        path: 'mydesktop',
        name: 'mydesktop',
        component: () => import('../views/user/myDesktop/MyDesktop.vue')
      }, {
        path: 'library',
        name: 'library',
        component: () => import('../views/user/library/Library.vue')
      }, {
        path: 'personal',
        name: 'personal',
        component: () => import('../views/user/personal/Personal.vue')
      }, {
        path: 'help',
        name: 'help',
        component: () => import('../views/user/help/Help.vue')
      }
    ]
  },

  {
    path: '/news/:id',
    name: 'news',
    hidden: true,
    component: () => import('../views/news/News.vue')
  }
]

//异步挂载的路由
//动态需要根据权限加载的路由表 
export const asyncRouterMap = [
  {
    path: '/pandect',
    name: 'pandect',
    component: Admin,
    meta: {
      title: '数据总览',
      icon: 'el-icon-house',
      check: true
    }
  }, {
    path: '/product',
    name: 'product',
    redirect: { name: 'launch' },
    component: Admin,
    meta: {
      title: '产品',
      icon: 'el-icon-s-grid',
      check: false
    },
    children: [
      {
        path: 'launch',
        name: 'launch',
        component: () => import('../views/admin/product/launch/Launch.vue'),
        meta: {
          title: '发布',
          check: false
        }
  	   }
    ]
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  // 只将固定路由挂载
  routes: constantRouterMap
})

export default router

router.beforeEach((to, from, next) => {
  // 判断后端是否清除session
  if (sessionStorage.getItem('sessionid')) {
    // 判断是否需要进行动态添加权限
    if (!store.getters.getAuth) {
      store.dispatch('getInfo').then(res => {
        if (res.length > 0) {
          // 动态将路由进行挂载
          res.forEach(item => {
            router.addRoute(item)
          })
        }
        next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
      })
    } else {
      // 若当前用户为  user普通用户   跳转到后台或登录界面,路由重定向到user界面
      if (store.getters.getAuth === 'user' && (to.path === '/login' || to.path === '/' || asyncRouterMap.indexOf(to.name) >= 0)) {
        next('/user')
        //  若当前用户为   管理用户  跳转到登录界面,路由重定向到管理台首页-----/pandect界面
      } else if ((to.path === '/login' || to.path === '/') && store.getters.getAuth === 'admin') {
        next('/pandect')
      } else {
        next()
      }
    }
  } else {
    // 路由白名单,即可直接跳转路由
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next('/login')
    }
  }
})

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import { getInfo } from '@/api/login/login.js'
import { asyncRouterMap, constantRouterMap } from '@/router/index.js'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    auth: undefined,
    routers: constantRouterMap,
    addRouters: [],
    asyncRouterMap: [],
    roles: []
  },

  getters: {
    getSessionid: state => {
      return state.sessionid
    },
    getToken: state => {
      return state.token
    },
    getAuth: state => {
      return state.auth
    },
    roles: state => {
      return state.roles
    },
    addRouters: state => {
      return state.addRouters
    },
    asyncRouterMap: state => {
      return state.asyncRouterMap
    }
  },

  mutations: {
    SET_ID (state, sessionid) {
      state.sessionid = sessionid
    },
    SET_TOKEN (state, token) {
      state.token = token
    },
    SET_USER (state, auth) {
      state.auth = auth
    },
    SET_ROLES (state, roles) {
      state.roles = roles
    },
    SET_ROUTERS: (state, routers) => {
      // 用户拥有权限的路由
      state.addRouters = routers
      // 用户所有路由(公共路由+拥有权限的路由)
      state.routers = constantRouterMap.concat(routers)
    },
    SET_ASYNCROUTER: (state, asyncRouterMap) => {
      state.asyncRouterMap = asyncRouterMap
    }
  },

  actions: {
    // 异步通过seesionid获取用户的登录权限,并将用户的权限进行存储
    getInfo ({ commit, state }) {
      return new Promise((resolve, reject) => {
        // 接口:获取用户权限
        getInfo().then(response => {
          const info = response.info.keys

          sessionStorage.setItem('sessionid', '21123')

          if (info.length === 0) {
            commit('SET_USER', 'user')
          } else {
            commit('SET_USER', 'admin')
          }

          const accessedRouters = asyncRouterMap.filter(v => {
            if (hasPermission(info, v)) {
              if (v.children && v.children.length > 0) {
                v.children = v.children.filter(child => {
                  if (hasPermission(info, child)) {
                    return child
                  }
                  return false
                })
                return v
              } else {
                return v
              }
            }
            return false
          })
          commit('SET_ROUTERS', accessedRouters)
          commit('SET_ASYNCROUTER', asyncRouterMap)

          resolve(accessedRouters)
        }).catch(error => {
          reject(error)
        })
      })
    }
  },

  modules: {}
})

// 判断该路由是否含有该权限
function hasPermission (roles, route) {
  if (route.name) {
    return roles.indexOf(route.name) >= 0
  } else {
    return true
  }
}

登录login.vue

...
handleLogin () {
      // 接口:登录,并将登录信息存储
      Login.loginByUsername(this.loginForm.username, this.loginForm.password).then(res => {
        const info = res.info.keys

        sessionStorage.setItem('sessionid', '21123')

        store.commit('SET_ROLES', info)
        if (info.length === 0) {
          // 跳转到前台
          this.$router.push({ path: '/user' })
        } else {
          // 跳转到后台
          this.$router.push({ path: '/pandect' })
        }
      })
    }

api —

loginByUsername.json 和 getInfo

{
  "code": 0,
  "user":{
    "user": 15
  },
  "info": {
    "keys": [
      "pandect",
      "deskTop",
      "serviceDeskTop",
      "product",
      "launch",
      "quota",
      "setQuota",
      "introduce",
      "account",
      "permission",
      "system",
      "log",
      "about",
      "copyright",
      "authorization"]
  }
}

--------内容先空着,等我下次一起补上-------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值