登录页面
在登录页面添加如下逻辑,即用账号密码请求后端获取token并保存,然后跳转至首页。
submitForm(loginForm) {
this.$refs[loginForm].validate((valid) => {
if (valid) {
let userinfo = this.loginForm;
login(userinfo).then((res) => {
let userList = res.user;
setToken("Token", userList.token);
this.$router.push({ path: "/" });
this.$store.dispatch("initLeftMenu"); //设置左边菜单始终为展开状态
});
}
});
},
权限控制
import router from "./router";
import store from "./store";
import { getToken } from "./utils/auth"; // 验权(从cookie中获取)
import { getUserInfo } from "./api/user";
import { ElMessage } from "element-plus";
function hasPermission(roles, permissionRoles) {
if (roles.indexOf("admin") >= 0) return true;
if (!permissionRoles) return true;
return roles.some((role) => permissionRoles.indexOf(role) >= 0);
}
const whiteList = ["/login"]; //不重定向白名单
router.beforeEach((to, from, next) => {
const browserHeaderTitle = to.meta.title;
store.commit("SET_BROWSERHEADERTITLE", {
browserHeaderTitle: browserHeaderTitle,
});
// 点击登录时,拿到了token并存入了cookie,保证页面刷新时,始终可以拿到token
if (getToken("Token")) {
if (to.path == "/login") {
next({ path: "/" });
} else {
// 用户登录成功之后,每次点击路由都进行了角色的判断;
if (store.getters.roles.length == 0) {
let token = getToken("Token");
getUserInfo({ token: token })
.then()
.then((res) => {
let userList = res.userList;
store.commit("SET_ROLES", userList.roles);
store.commit("SET_NAME", userList.name);
store
.dispatch("GenerateRoutes", { roles: userList.roles })
.then(() => {
// 根据roles权限生成可访问的路由表
const routers = store.getters.addRouters;
routers.forEach((route) => {
router.addRoute(route);
});
next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
});
})
.catch((err) => {
store.dispatch("LogOut").then(() => {
ElMessage.error(err || "Verification failed, please login again");
next({ path: "/" });
});
});
} else {
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
if (hasPermission(store.getters.roles, to.meta.roles)) {
next();
} else {
next({ path: "/401", replace: true, query: { noGoBack: true } });
}
}
}
} else {
if (whiteList.indexOf(to.path) != -1) {
//点击退出时,会定位到这里
next();
} else {
next("/login");
}
}
});
router.afterEach(() => {
setTimeout(() => {
const browserHeaderTitle = store.getters.browserHeaderTitle;
window.document.title = browserHeaderTitle;
}, 0);
});
根据role进行路由过滤
import { asyncRouterMap, constantRouterMap } from "@/router";
/**
* 通过meta.role判断是否与当前用户权限匹配
* @param roles
* @param route
*/
function hasPermission(roles, route) {
// roles为权限身份数组
if (route.meta && route.meta.roles) {
return roles.some((role) => route.meta.roles.indexOf(role) >= 0);
} else {
return true;
}
}
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param asyncRouterMap
* @param roles
*/
function filterAsyncRouter(asyncRouterMap, roles) {
// 返回满足条件的子路由对象
const accessedRouters = asyncRouterMap.filter((route) => {
if (hasPermission(roles, route)) {
if (route.children && route.children.length) {
// route.children重新过滤赋值;
route.children = filterAsyncRouter(route.children, roles);
}
return true; // 返回该权限路由对象;
}
return false;
});
return accessedRouters;
}
const permission = {
state: {
routers: constantRouterMap,
addRouters:[],
},
getters: {
permission_routers: (state) => state.routers, // 所有路由
addRouters: state => state.addRouters, //权限过滤路由
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers,
state.routers = constantRouterMap.concat(routers); // 总路由
},
},
actions: {
// 根据角色,重新设置权限路由;并保存到vuex中,SET_ROUTERS;
GenerateRoutes({ commit }, data) {
return new Promise((resolve) => {
let roles = data.roles;
let accessedRouters = "";
if (roles.indexOf("admin") >= 0) {
// 如果是管理员,直接将权限路由赋值给新路由;
accessedRouters = asyncRouterMap;
} else {
// 非管理员用户,如roles:['editor','developer'],则需要过滤权限路由数据
accessedRouters = filterAsyncRouter(asyncRouterMap, roles);
}
commit("SET_ROUTERS", accessedRouters);
resolve();
});
},
},
};
export default permission;
登出页面
LogOut({ commit, reqData }) {
// eslint-disable-next-line no-unused-vars
return new Promise((resolve, reject) => {
logout(reqData).then((response) => {
console.log(response);
commit("SET_ROLES", []);
commit("SET_NAME", []);
removeToken("Token");
resolve();
});
});
},