vue路由权限+token验证

vue路由权限–子路由的权限

vue路由权限+token验证_第1张图片
1.登陆
login.vue

this.$store.dispatch('Login',this.loginForm)
.then(res=>{
     this.loading = false;
     this.$router.push('/');
})//登陆用vuex,这样方便全局的管理

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import permission from './modules/permission'
Vue.use(Vuex)
export default new Vuex.Store({
  modules: {
    user,
    permission
  }
})//这里分成两个模块方便日后的维护

user.js

export default {
  state: {
      token:getToken(),//这就是从网页中存存储的token取出
      //下面有token存在哪的解释,当然你存在哪他就从哪取出来
      roles:[]//角色权限的数组
  },
  getters:{
    token:state=>state.token,
    roles:state=>state.roles,
  },
  mutations: {
    SET_TOKEN(state,token){
        state.token = token;
    },
    SET_ROLES(state,roles){
        state.roles = roles;
    }
  },
  actions: {
    Login({commit},user){
        return new Promise((resolve,reject)=>{
            loginApi(user).then(res=>{//这是请求登陆接口的ajax
               commit('SET_TOKEN',res.data.token);//这时候后端会返回一个token
               setToken(res.data.token);//把后端返回的token存起来
               //这里是封装了个方法把token存在了cookie中
               //你也可以存在sessionStorage或者locationStorage中
               resolve(res);
            }).catch(err=>{
                reject(err);
            })
        })
    },
    GetInfo({commit,state}){//这是获取用户的角色信息
    	//是超级管理员还是普通的
    	//这里返回的格式是数组['inputs']或者['admin']...
        return new Promise((resolve,reject)=>{
            getInfoApi(state.token).then(res=>{//请求接口
                commit('SET_ROLES',res.data.roles);
                resolve(res.data);
            }).catch(err=>{
                reject(err);
            })
        })
    },
  },
}

permission.js

//这里是两个分类路由
//asyncRouters动态变化的路由
//constantRouters永远不变的路由,就是什么权限都有他
import {asyncRouters,constantRouters} from '@/router/index.js'
function filterAsyncRoutes(routes, v) {//这是对路由函数的定义
  const res = []
  routes.forEach((route,i) => {//对每个路由进行判断
  	//深拷贝,防止第二次登陆换权限的时候路由没有发生改变
  	//这里如果你不用深拷贝直接赋值的话,你换账号登陆的时候他路由加载会不完全
  	//有兴趣你可以试试
    var newRoute = deep({},route)
    newRoute.children = route.children.filter(item=>{//对权限进行过滤
      if(item.meta && item.meta.roles && v.some(role => item.meta.roles.includes(role))){
      	//刚才vuex中定义的roles这时候就用到了
      	//判断子路由中是否存在roles这个值有就返回
        return  item
      }
    })
    if(newRoute.children.length>0){//判断下是否有子路由,有的话就添加
      res.push(newRoute)
    }
  });
  return res;
}
const state = {
  routes: []//动态路由存在vuex中这样没次刷新的时候他都能判断一次提高安全性
}
const getters = {
  permission_routes: state => state.routes,  //权限路由
}
const mutations = {
  SET_ROUTES: (state, routes) => {
    state.routes = constantRouters.concat(routes)//和永远不变的路由添加到一起
  }
}
const actions = {
  GenerateRoutes({ commit }, roles) {//角色数组['']
    return new Promise(resolve => {
      let accessedRoutes;
      if (roles.includes("admin")) {//如果权限是admin就不用判断了就都添加进去
        accessedRoutes = asyncRouters ;
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRouters, roles) //不是管理员跟据meta过滤数据
      }
      commit('SET_ROUTES', accessedRoutes);
      resolve(accessedRoutes);
    })
  }
}
export default {
  state,
  getters,
  mutations,
  actions
}

路由守卫的js

router.beforeEach(async(to,from,next)=>{
        if(to.path=='/login'){// 1.判断是否登陆界面
            next();
        }else{
            //如果不是登陆就要进行判断了
            // 这里是动态获取这个权限,
            //因为存进vuex刷新是时候vuex数据就会消失,所以需要重新进行请求
            //如果没刷新就不用了直接next()
            var hasRoles = store && store.getters.roles && store.getters.roles.length > 0;
            if(hasRoles){
                next();
            }else{
                //发送请求获取对应的角色信息
                try{
                    var roles = await store.dispatch('GetInfo');//这就是vuex   user.js中执行
                    let rolesName = roles.roles;//得到角色
                    var accessRoutes = await store.dispatch('GenerateRoutes',rolesName);//这里就是permission.js
                    router.addRoutes(accessRoutes)  //获取完路由的信息就动态添加进去
                    next({...to})//跳转
                }catch(error){
                    console.log(error)//这里我希望你是打印出来
                    //因为你是try  catch你要不打印报错你就不会看见
                    //找半天不也不知道原因
                    next({path:'/login'});//出现错误就不让他进里面看了直接退出登陆。
                }
            }
        }
})

最后说下这token吧,我是放在请求头进行交互的,因为每次都得带着它所以我给他些在了axios的请求拦截中

import axios from 'axios'
var service = axios.create({
    baseURL:'http://localhost:9000/',
    withCredentials:true,//允许cookie
})
// 请求拦截将头部放入token
service.interceptors.request.use(
    config =>{
        config.headers['token'] = getToken();//根据刚才说的token存哪从哪取
        return config;
    },
    error =>{
        return Promise.reject(error);
    }
)

你可能感兴趣的:(vue权限管理)