本博文是在权限管理模块的前后端都已经搭建完成的基础上,针对其中的bug进行解决的。
1、权限管理流程
(1)前端项目启动
前端项目启动后,会自动访问 http://localhost:9528/ ,但是实际跳转的是http://localhost:9528/login
。
这是由于在src目录下的permission.js中定义了路由跳转之前的判断规则。
// 该操作会在路由跳转之前执行
router.beforeEach(async(to, from, next) => {
// start progress bar
NProgress.start()
// 再路由跳转之前获取用户存储在cookie中token
const hasToken = getToken()
// 已登录,进入这里
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({
path: '/' })
NProgress.done()
} else {
// determine whether the user has obtained his permission roles through getInfo
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if (hasRoles) {
next()
} else {
try {
const {
roles } = await store.dispatch('GetInfo')
// generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
// dynamically add accessible routes
router.addRoutes(accessRoutes)
next({
...to, replace: true })
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('FedLogOut')
Message.error(error || 'Has Error')
next(`/login?redirect=${
to.path}`)
NProgress.done()
}
}
}
}
// 没有登录,进入这里
else {
/* has no token*/
// 验证要跳转的路由地址是否在白名单中
if (whiteList.indexOf(to.path) !== -1) {
// 在白名单中,直接跳转
next()
} else {
// 不在白名单中,跳转到登录页面
next(`/login?redirect=${
to.path}`)
NProgress.done()
}
}
})
以上的代码,在路由跳转之前进行判断,如果已经登录(判断标准为是否可以获取到token),直接跳转到相关页面。没有登录,跳转到登录页面进行登录。
其中获取token的方法由 import { getToken } from ‘@/utils/auth’ 导入,该js文件中定义了token从cookie中获取。
export function getToken() {
return Cookies.get(TokenKey)
}
(2)没有登录token的执行流程
// 路由跳转的白名单
const whiteList = ['/login', '/auth-redirect']
// 没有登录,进入这里
else {
/* has no token*/
// 验证要跳转的路由地址是否在白名单中
if (whiteList.indexOf(to.path) !== -1) {
// 在白名单中,直接跳转
next()
} else {
// 不在白名单中,跳转到登录页面
next(`/login?redirect=${
to.path}`)
NProgress.done()
}
}
先判断是否在白名单中,是则跳转。
不是的话,跳转到登录页面。
以上两个步骤都是在获取登录之后的信息,那么是如何登录的呢,页面上定义的跳转到登录页面的代码为:
next(`/login?redirect=${
to.path}`)
要跳转的页面为:src/views/login/index.vue,在该页面上有一系列的校验方法去获取正确的表单信息,然后点击登录时的处理方法为;
<el-button :loading="loading" type="primary" style="width:100%;" @click="handleLogin">
登录
</el-button>
<script>
handleLogin() {
// 表单数据校验
this.$refs.loginForm.validate(valid => {
if (valid) {
// debugger
this.loading = true
// 调用函数进行登录
this.$store.dispatch('Login', this.loginForm).then(() => {
this.loading = false
this.$router.push({
path: this.redirect || '/' })
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}