vue 实现用户登录验证+权限管理+动态路由
近期要实现一个公安偷窃案件管理系统的登陆功能,搜遍网上发现没有能直接copy的代码,只好自己摸索踩坑,好死不死终于脱坑,这边把实现过程尽可能详细复现一遍,就不展开原理说明(毕竟我也不会),以下包含用户登录验证+权限管理+动态路由等功能。
一、技术栈
vue
+vuex
+vue-router
+ant-design-vue
+axios
+mockjs2
二、新建项目
前提条件:在个人电脑上安装好nodejs
(我的是v12.18.3
)之后,利用nodejs
自带的npm
安装好vue
(我的是vue/cli 4.5.4
),再在命令行中通过以下指令在指定目录下按装脚手vue-cli
npm install -g @vue/cli-init
新建自定义项目
vue init webpack your-project
由于代码检查、测试之类的功能(ESlint, unit tests, e2e tests)目前对我还不是必须的,所以我都没有选择安装,整个项目的配置项如下:
在开始Coding前,在项目根目录下好项目的依赖包:
cd your-project
npm i ant-design-vue axios lodash mockjs2 nprogress vuex store
为避免版本问题,把我个人包安装之后的package.json
中的dependencies
贴出来:
"dependencies": {
"ant-design-vue": "^1.6.5",
"axios": "^0.20.0",
"core-js": "^3.6.5",
"lodash": "^4.17.20",
"mockjs2": "^1.0.8",
"nprogress": "^0.2.0",
"store": "^2.0.12",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
三、功能实现
先讲思路,让大伙有个大概的印象,不至于看代码云里雾里。
- 我们将储存在将
storage
中的token
作为用户是否登录的标志,如果当前storage
中有token
,表明当前系统已被登录 - 将系统所有页面分为两类,需要登录的
Home.vue
,不需要登录的Login.vue
- 前端每次跳转路由时,做以下判断:
- 前往登录页面时
- 如果已登录过,需要先注销退出并且清除
token
再跳转 - 如果没有登录,直接跳转
- 验证用户输入的用户名和密码,如果成功,往
storage
中填入token
- 验证用户输入的用户名和密码,如果成功,往
- 如果已登录过,需要先注销退出并且清除
- 前往非登录页面时
- 用户无需登录就能访问的页面(如注册、找回密码、访客模式等情况)
- 直接跳转
- 用户需要登录才能访问的页面
- 如果用户还没登陆
- 跳向登录页
- 如果用户已经登陆
- 如果用户拥有查看该页面的权限,直接跳转
- 如果用户没有查看该页面的权限,弹出无权限提醒,跳转到登陆页
- 如果用户还没登陆
- 用户无需登录就能访问的页面(如注册、找回密码、访客模式等情况)
- 前往登录页面时
接下来从技术栈的角度补充几点:
- 在
vue-router
的beforeEach
方法中实现以上逻辑,判断前端跳转去向; - 出于系统简单考虑,不引入后端,用
mockjs2
模拟的用户信息作为拦截axios
发起的服务请求响应; - 通过
Vuex.Store
做userName
,userRole
的状态管理;
贴上项目目录结构图(src):
src
api
login.js //请求接口
directives
auth.js //自定义的权限管理指令
mock
service
auth.js //模拟用户登录数据
util.js //辅助生成数据
request
http.js //axios请求、响应、异常拦截器
router
index.js //路由管理
store
module
user.js //userName,userRole状态管理
index.js //vuex全局配置
mutation-types.js//状态类型定义
util
auth.js //路由跳转时的权限判断
views
User
Login.vue //登录页面
Main
Home.vue //登录后的Home页面
AdminPage.vue // 登录后管理员才能查看的页面
403.Vue //无权限提醒页面
App.vue //系统全局页面
main.js //系统全局包管理
接下来给大伙无脑贴几个主要代码
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import antd from 'ant-design-vue'
import Auth from './directives/auth'
Vue.config.productionTip =