设计思路
- 设计两个不同的RouterMap用来表示不同的权限访问页面,constantRouterMap表示无需权限的访问页面,asyncRouterMap表示需要权限访问的页面。
- 在index.js中创建VueRouter,包括基础配置以及权限页面的配置。
- 从sessionStorage取出role值,获得用户的身份,根据不同的身份选择是否添加权限访问的路由。
- 当sesionStorge过期时,取出localStoge的token,重新向服务端发送请求设置sessionStorage,重复第三步。
- 配置beforeEach函数,每次页面跳转时进行判断,如果sessionStorage和localStorage都为空,就回到登录页面。
代码编写
constantRouter.js:在该页面,创建不需要认证就能访问的路由
const constantRouterMap = [{
path: '/login',
meta: {
title: '用户登录'
},
component: (resolve) => require(['../views/login.vue'], resolve)
},
{
path: '/index',
meta: {
title: '主页',
},
component: (resolve) => require(['../views/index/index/index.vue'], resolve)
},
}
export default constantRouterMap;
asyncRouter.js:在该页面,创建需要用户认证才能访问的路由,在meta中添加premission数组,表示可以访问的权限。
const asyncRouterMap = [
{
path: '/mine',
meta: {
title: '我的',
permission: ["user", "admin"]
},
component: (resolve) => require(['../views/mine/mine.vue'], resolve)
},
}
export default asyncRouterMap;
index.js:在该页面,进行基础配置,和权限路由配置的逻辑处理
import ConstantRouters from "./constantRouter";
import asyncRouters from "./asyncRouter";
import VueRouter from 'vue-router';
import Vue from 'vue';
Vue.use(VueRouter);
const RouterConfig = {
mode: 'history',
routes: ConstantRouters,
base: '/platform/',
};
NewRouter方法:实例化vue-router,根据sessionStorage的role值,添加不同的路由。若sessionStorage不存在,取出localStorage中的token值重新请求,并存入sessionStorage中。
const router = NewRouter();
function NewRouter() {
let router = new VueRouter(RouterConfig);
if (sessionStorage.getItem("role")) {
//若存在sessionStorage保存的ROLE值(说明单次会话未结束),则直接生成动态权限路由表
router.addRoutes(routerMatch(sessionStorage.getItem("role")));
} else if (localStorage.getItem("token")) {
//若不存在localStorage保存的ROLE值(单次会话已结束,但token不一定失效),则利用token重新获取之
getUserInfo();
}
return router;
}
function routerMatch(role) {
let routers = [];
for (let index in asyncRouters) {
//取出asyncRouters中的字段permission,和sessionStorage中的role进行比对,如果匹配就添加到新的录用。
let permission = asyncRouters[index].meta.permission;
if (permission.indexOf(role) !== -1) {
routers.push(asyncRouters[index]);
}
}
routers.push({
path: '*',
meta: {
title: '访问受限',
},
component: (resolve) => require(['../views/errorPage.vue'], resolve)
});
return routers;
}
//向服务器请求用户基本信息并建立会话缓存
function getUserInfo(callback = function () {}) {
//向服务器请求用户基本信息
axios({
method: 'get',
url: baseURL + '/userInfoService/getUserBaseInfo',
headers: {
Authorization: localStorage.getItem("token"),
}
}).then((response) => {
//token未失效时
let responseData = response.data;
// 获取用户基本信息并存入sessionStorage
sessionStorage.setItem("username", responseData.msg.username);
sessionStorage.setItem("role", responseData.msg.role);
//生成动态权限路由表
router.addRoutes(routerMatch(responseData.msg.role));
//执行回调
callback();
}).catch((error) => {
console.log(error)
//返回登录页
localStorage.removeItem("token");
router.push("/login");
//执行回调
callback();
})
}
beforeEach函数:为vue-router添加上beforeEach函数,每次跳转页面前进行拦截,对于token不存在的新用户拦截跳转到登录页面
//路由转发拦截器
router.beforeEach((to, from, next) => {
if (localStorage.getItem("token") != null) {
router.push("/login");
} else {
next();
}
});