litemall源码阅读3.03管理后台前端litemall-admin登录验证
首先熟悉一下token。
再熟悉一下前后端分离的token验证机制
之后看代码。litemall-admin/src/permission.js
router.beforeEach((to, from, next) => {
NProgress.start() // 这是网页内容顶端的进度条。
if (getToken()) { // 主要函数就在这里了,这里返回的是false。所以我们直接跳转到else块
{
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next()
} else {
next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}
})
我们进入getToken函数:
使用js-cookie组件读取cookie中保存的token。
当然现在是读取不到的。之后重定向到了/login。
查看login/index.vue源码。
其实我对template块的疑虑很多,搜索了很久都是千篇一律。这里的一些代码就当作elementUI的固定写法了。
关于promise我看到这里终于理解是个啥了。总结来说就是为了异步执行的一种方式。在c++里面经常要用到指针函数作为callback。
而使用这种语法可以把执行函数与callback写在一起。
handleLogin() {
this.$refs.loginForm.validate(valid => { //这里应该是调用了配置的自定义校验规则,但我缺少对elementUI的了解,语法有点不理解。。。
if (valid && !this.loading) { //valid验证密码是否符合规则,isloading应该是为了防止客户不停的点击登录
this.loading = true
this.$store.dispatch('LoginByUsername', this.loginForm).then(() => { //这里的语法比较长,请看vuex组合Action与promise的catch
this.loading = false
this.$router.push({ path: this.redirect || '/' }) //登录成功后重定向到刚才访问的url。
}).catch(response => {
this.$notify.error({
title: '失败',
message: response.data.errmsg
})
this.loading = false
})
} else {
return false
}
})
}
将token写入cookies是在LoginByUsername中进行的。litemall-admin/src/store/modules/user.js
LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => { //因为返回值要组合then()所以这边返回一个Promise对象
loginByUsername(username, userInfo.password).then(response => {
const token = response.data.data.token
commit('SET_TOKEN', token) //vuex存储token
setToken(token) //将token写入cookies
resolve()
}).catch(error => {
reject(error)
})
})
},
继续看loginByUsername函数。
向/auth/login发送post请求。
那么这个请求的根目录是怎么确定的呢?在axios的初始化函数中。
那么这个UVE_APP_BASE_API是怎么确定的呢?
就在这里。
登录成功。
后台的登录验证过程请看这里。
登录成功后,就到了页面跳转。
首先在文件litemall-admin/src/views/login/index.vue中
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
给this.redirect进行了赋值。在登录成功后:
this.$router.push({ path: this.redirect || '/' })
进行页面跳转,跳转到登录前申请的url。