赞
踩
用户前台登录后,后台返回一个token,将该token存储到store中,并设置到header中,每次发起请求时都会携带该token,用于后台进行权限校验
- // 登录方法 login.vue
- handleLogin() {
- this.$refs.loginForm.validate((valid) => {
- if (valid) {
- this.loading = true;
- this.$store
- .dispatch("user/login", this.loginForm)
- .then(() => {
- this.$router.push({ path: this.redirect || "/" });
- this.loading = false;
- })
- .catch(() => {
- this.loading = false;
- });
- } else {
- console.log("error submit!!");
- return false;
- }
- });
- },

在store 的user.js中定义了该方法
- login({ commit }, userInfo) {
- const { userName, userPassword } = userInfo;
- return new Promise((resolve, reject) => {
- login({ userName: userName.trim(), userPassword: userPassword })
- .then((response) => {
- const { data } = response;
- commit("SET_TOKEN", data.token);
- setToken(data.token);
- resolve();
- })
- .catch((error) => {
- reject(error);
- });
- });
- },
-

- const mutations = {
- RESET_STATE: (state) => {
- Object.assign(state, getDefaultState());
- },
- SET_TOKEN: (state, token) => {
- state.token = token;
- },
- SET_NAME: (state, name) => {
- state.name = name;
- },
- SET_AVATAR: (state, avatar) => {
- state.avatar = avatar;
- },
- SET_AUTHORITIES: (state, authorities) => {
- state.authorities = authorities;
- },
- };

此时登录成功后,后台将返回一个token
在请求拦截器中将token添加到请求头上,在响应拦截器中设置未登录状态访问时跳转到登录页面
- import axios from "axios";
- import { MessageBox, Message } from "element-ui";
- import store from "@/store";
- import { getToken, removeToken } from "@/utils/auth";
- import router from "@/router";
-
- // create an axios instance
- const service = axios.create({
- baseURL: "http://localhost:8080", // url = base url + request url
- timeout: 5000, // request timeout
- });
-
- // request interceptor
- service.interceptors.request.use(
- (config) => {
- if (store.getters.token) {
- config.headers["token"] = getToken();
- }
- return config;
- },
- (error) => {
- console.log(error);
- return Promise.reject(error);
- }
- );
-
- // response 拦截器
- service.interceptors.response.use(
- (response) => {
- const res = response.data;
-
- // if the custom code is not 20000, it is judged as an error.
- if (res.code !== 200 && res.code !== 201) {
- Message({
- message: res.message || "Error",
- type: "error",
- duration: 5 * 1000,
- });
-
- // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
- if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
- // to re-login
- MessageBox.confirm(
- "You have been logged out, you can cancel to stay on this page, or log in again",
- "Confirm logout",
- {
- confirmButtonText: "Re-Login",
- cancelButtonText: "Cancel",
- type: "warning",
- }
- ).then(() => {
- store.dispatch("user/resetToken").then(() => {
- location.reload();
- });
- });
- }
- if (res.code == 401) {
- removeToken();
- router.replace({
- path: "/login",
- });
- }
- return Promise.reject(new Error(res.message || "Error"));
- } else {
- return res;
- }
- },
- (error) => {
- console.log("err" + error); // for debug
- Message({
- message: error.message,
- type: "error",
- duration: 5 * 1000,
- });
- return Promise.reject(error);
- }
- );
-
- export default service;

在permission.js 中进行相关代码编写 (获取用户的信息,动态路由的生成加载)
router.beforeEach()路由拦截()
- import router from "./router";
- import store from "./store";
- import { Message } from "element-ui";
- import NProgress from "nprogress"; // progress bar
- import "nprogress/nprogress.css"; // progress bar style
- import { getToken } from "@/utils/auth"; // get token from cookie
- import getPageTitle from "@/utils/get-page-title";
-
- NProgress.configure({ showSpinner: false }); // NProgress Configuration
-
- const whiteList = ["/login"]; // no redirect whitelist
-
- router.beforeEach(async (to, from, next) => {
- // start progress bar
- NProgress.start();
-
- // set page title
- document.title = getPageTitle(to.meta.title);
-
- // determine whether the user has logged in
- const hasToken = getToken();
- const hasRoles =
- store.state.user.authorities && store.state.user.authorities.length > 0;
- // 如果有token再跳转到登录页面时,根据获取的角色信息进行页面跳转
- if (hasToken) {
- if (to.path === "/login") {
- if (store.state.user.authorities) {
- if (store.state.user.authorities.includes("ROLE_ADMIN")) {
- next({ path: "/" });
- } else {
- next({ path: "/user" });
- }
- } else {
- next({ path: "/" });
- }
- NProgress.done();
- } else {
- // 获取登录用户名 如果用户名存在说明用户已经登录且获得了用户信息,直接放行,如果没有用户名,就进行用户信息获取
- const hasGetUserInfo = store.getters.name;
- if (hasGetUserInfo) {
- next();
- } else {
- try {
- //判断用户角色是否存在
- if (!hasRoles) {
- let userInfo = await store.dispatch("user/getInfo"); // 获取用户信息
- // 根据获得到的用户信息,获取用户角色信息并动态生成路由
- let routes = await store.dispatch(
- "permission/getAsyncRoutes",
- userInfo.user.authorities
- );
- router.options.routes = routes;
- router.addRoutes(routes); // 将生成的动态路由添加到原先的路由中
- next({ ...to, replace: true }); // 保证路由已挂载
-
- // 根据用户角色进行登录后的首页面跳转
- if (store.state.user.authorities) {
- if (store.state.user.authorities.includes("ROLE_ADMIN")) {
- next({ path: "/" });
- } else {
- next({ path: "/user/user" });
- }
- }
- }
- } catch (error) {
- // remove token and go to login page to re-login
- await store.dispatch("user/resetToken");
- Message.error(error || "Has Error");
- next(`/login`);
- NProgress.done();
- }
- }
- }
- } else {
- /* has no token*/
- if (whiteList.indexOf(to.path) !== -1) {
- // in the free login whitelist, go directly
- next();
- } else {
- // other pages that do not have permission to access are redirected to the login page.
- next(`/login`);
- NProgress.done();
- }
- }
- });
-
- router.afterEach(() => {
- // finish progress bar
- NProgress.done();
- });

获取用信息的方法定义在store的user.js中
- // 获取用户信息
- getInfo({ commit, state }) {
- return new Promise((resolve, reject) => {
- getInfo()
- .then((response) => {
- const { data } = response;
- if (!data) {
- return reject("Verification failed, please Login again.");
- }
- const { username, authorities } = data.user;
- // 将用户名,和用户角色信息存储到store中
- commit("SET_NAME", username);
- commit("SET_AUTHORITIES", authorities);
- resolve(data);
- })
- .catch((error) => {
- reject(error);
- });
- });
- },

在store 的 permission.js 为动态路由的相关方法和存储
- import { asyncRoutes, constantRoutes } from "@/router";
- /**
- * 通过meta中的roles信息判断用户是否有权限
- * @param roles
- * @param route
- */
- function hasPermission(roles, route) {
- if (route.meta && route.meta.roles) {
- return roles.some((role) => route.meta.roles.includes(role));
- } else {
- return true;
- }
- }
-
- /**
- * 根据角色和配置生成当前用户的路由
- * @param {array} routes 配置的路由
- * @param {array} roles 用户角色
- */
- let GenerateRoutes = (routes, roles) => {
- let res = [];
- routes.forEach((route) => {
- const tmp = { ...route };
-
- if (hasPermission(roles, tmp)) {
- if (tmp.children) {
- tmp.children = GenerateRoutes(tmp.children, roles);
- }
- // console.log(tmp);
- res.push(tmp);
- }
- });
-
- return res;
- };
-
- const getDefaultState = () => {
- return {
- roles: [],
- routes: constantRoutes, // 用于配置页面导航等
- };
- };
- const state = getDefaultState();
- const mutations = {
- SET_ROLES: (state, roles) => {
- state.roles = roles;
- },
- SET_ROUTES: (state, routes) => {
- state.routes = routes;
- },
- };
-
- const actions = {
- /**根据角色获取路由配置 */
- getAsyncRoutes({ commit }, roles) {
- let filterRoutes = GenerateRoutes(asyncRoutes, roles);
- let res = constantRoutes.concat(filterRoutes);
- commit("SET_ROUTES", res);
- return res;
- },
- };
-
- export default {
- namespaced: true,
- state,
- mutations,
- actions,
- };

将新增的js文件引入store的index.js文件中
- import Vue from "vue";
- import Vuex from "vuex";
- import getters from "./getters";
- import app from "./modules/app";
- import settings from "./modules/settings";
- import user from "./modules/user";
- import permission from "./modules/permission";
-
- Vue.use(Vuex);
-
- const store = new Vuex.Store({
- modules: {
- app,
- settings,
- user,
- permission,
- },
- getters,
- });
-
- export default store;

路由文件
- import Vue from "vue";
- import Router from "vue-router";
-
- Vue.use(Router);
-
- /* Layout */
- import Layout from "@/layout";
-
- // 默认路由
- export const constantRoutes = [
- {
- path: "/login",
- component: () => import("@/views/login/index"),
- hidden: true,
- },
- {
- path: "/404",
- component: () => import("@/views/404"),
- hidden: true,
- },
- ];
- // 自定义动态路由,在meta中添加了roles,通过roles中是角色进行动态生成不同角色的动态路由
- export const asyncRoutes = [
- {
- path: "/",
- component: Layout,
- redirect: "/employee",
- meta: { roles: ["ROLE_ADMIN"] },
- children: [
- {
- path: "employee",
- name: "Employee",
- component: () => import("@/views/employee/index"),
- // meta: { title: "员工管理", icon: "el-icon-s-custom" },
- meta: {
- roles: ["ROLE_ADMIN"],
- title: "员工管理",
- icon: "el-icon-s-custom",
- },
- },
- ],
- },
- {
- path: "/user",
- component: Layout,
- meta: { roles: ["ROLE_DEPT", "ROLE_EMP"] },
- children: [
- {
- path: "user",
- name: "User",
- component: () => import("@/views/user/index"),
- meta: {
- roles: ["ROLE_DEPT", "ROLE_EMP"],
- title: "个人信息",
- icon: "el-icon-setting",
- },
- },
- ],
- },
- // 404 page must be placed at the end !!!
- { path: "*", redirect: "/404", hidden: true },
- ];
-
- const createRouter = () =>
- new Router({
- // mode: 'history', // require service support
- scrollBehavior: () => ({ y: 0 }),
- routes: constantRoutes,
- });
-
- const router = createRouter();
-
- // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
- export function resetRouter() {
- const newRouter = createRouter();
- router.matcher = newRouter.matcher; // reset router
- }
-
- export default router;

此时登录成功并获取到用户信息后,可在控制台看到存储到store中的信息
登录成功界面实例
管理员
部门经理
基本员工
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。