首页登陆事件一般有两种,点击登陆(click)和回车事件(keyup),触发的是同一个事件,上代码:
// 如下是登陆页form表单部分代码
用户登录
账号
密码
记住账号
忘记密码?
登 录
那么在输入密码点击(回车)登陆到跳转到首页,这之间发生了什么呢?
首先要知道,在用户登陆成功之后后台会返回一个token,一串字符串,前端需要存储这个token,可以保存在vuex里面或者cookie里或者localStorage或者别的地方,在每次发送请求时可以携带这个token(请求拦截,后续介绍),后台可以根据token判断当前用户状态(登退陆成功、退出登录、登陆超时等),从而返回相应的状态码。在axios里我们可以拦截响应,判断响应的状态码,然后根据不同的状态码去做不同的事情。
一步一步来,首页用户填写用户名密码,前台需要进行相应的处理,去掉用户名两端的空格,或者对密码进行加密,而接口可以直接在页面中请求,也可以用vuex管理,这个项目是放在vuex中管理的,代码:
// 用户名登录 此方法是在vuex 的action中管理的
LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim() // 用户名处理,去掉两端的空格
return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(res => {
if (res.code === 0) {
// 在每次登陆成功之后都将后台token保存在vuex及cookie中
commit('SET_TOKEN', res.data.token) // 保存tooken到vuex中
setToken(res.data.token) // 保存tooken到cookie中
resolve(res)
} else {
reject(res)
}
}).catch(error => {
reject(error)
})
})
},
上面用到了setToken,其实对cookie的操作方法的封装,如下:
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token' // cookie中用来存放tooken的名称
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
// localStorage.clear()
Cookies.remove(TokenKey)
return
}
('js-cookie' 的使用这里引用一篇文章,想了解可以看下,Cookie的使用(js-cookie插件))
vuex中封装好了登陆的方法,cookie的设置也定义好了,就可以直接登陆了,但是项目需要在登录成功之后记住用户名和密码,
由于是我做的,所以比较乱,用的是localStorage,在登陆成功之后将用户名和密码保存在本地,这里牵扯一个登陆密码的加密和解密过程,分享一下代码吧
import CryptoJS from 'crypto-js'
export default {// 加密
encrypt(word) {
var keyStr = 'abcdefgabcdefg12'
var key = CryptoJS.enc.Utf8.parse(keyStr)// Latin1 w8m31+Yy/Nw6thPsMpO5fg==
var srcs = CryptoJS.enc.Utf8.parse(word)
var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
return encrypted.toString()
},
// 解密
decrypt(word) {
var keyStr = 'abcdefgabcdefg12'
var key = CryptoJS.enc.Utf8.parse(keyStr)// Latin1 w8m31+Yy/Nw6thPsMpO5fg==
var decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
return CryptoJS.enc.Utf8.stringify(decrypt).toString()
}
}
那么现在可以正式登陆了:
handleLogin() {
this.$refs.loginForm.validate(valid => { // form表单的校验方法
this.loginForm.password = utils.encrypt(this.loginForm.password) // 对密码进行加密
if (valid) {
this.loading = true
// vuex中登陆方法调用
this.$store.dispatch('LoginByUsername', this.loginForm).then((res) => {
// 如果localStorage中不存在用户名,那么将用户名密码保存在localStorage中
if (!localStorage.getItem('userName') && localStorage['userName'] === undefined) {
localStorage.setItem('userName', this.loginForm.username)
localStorage.setItem('passWord', utils.decrypt(this.loginForm.password))
localStorage.setItem('checked', this.checked) // 保存记住用户名密码选择框勾选状态
} else {
// 如果用户名存在则判断用户名是否改变,切换用户时从新保存用户名密码
if (localStorage.getItem('userName') !== this.loginForm.username.toString()
&& localStorage.getItem('userName')) {
localStorage.setItem('userName', this.loginForm.username)
localStorage.setItem('passWord', utils.decrypt(this.loginForm.password))
localStorage.setItem('checked', this.checked)
}
}
this.$store.dispatch('GetUserLngAT')
this.loading = false
this.$router.push({ path: '/' }) // 路由指向为空会重定向到首页
// 如果没有勾选记住密码则清空密码
if (!this.checked) this.loginForm.password = ''
}).catch((data) => {
this.loading = false
this.loginForm.password = ''
// this.loginForm.password = utils.decrypt(this.loginForm.password)
this.$message({
type: 'info',
message: data.msg
})
})
} else {
// console.log('error submit!!')
this.loginForm.password = ''
return false
}
})
}
登陆成功之后便可以将tooken保存在本地缓存中,其中一个很重要的作用就是每次进入页面后可以去判断tooken是否存在,从而确认当前用户是否已经登陆,这一动作的完成可以放在router.beforeEach全局路由守卫中
前面说过在登陆成功后,后台会返回一个tooken,前台可以用不同方式保存这个tooken,在每次发起请求时需要携带这个tooken,以方便后台判断当前用户状态。那么如此我们便可以在axios里面拦截请求进行设置:
// 请求拦截器
service.interceptors.request.use(config => {
// Do something before request is sent
// 导出时 超时时间设为5min
if (config.responseType === 'blob') {
config.timeout = 1000 * 60 * 5
}
if (store.getters.token) {
// 让每个请求携带token-- ['XN-Auth']为自定义Header key
config.headers['XN-Auth'] = getToken()
}
return config
}, error => {
// Do something with request error
Promise.reject(error)
})
到这里可以算是正式登陆成功了,那么如何退出呢?
其实退出就好办了,只需要清楚本地存储的tooken信息即可,退出的方法还是通过vuex管理的:
// 前端 登出 同样是在action中管理
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
},
// 退出事件
logout() {
this.$confirm('确定退出系统?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'info'
}).then(() => {
this.$store.dispatch('FedLogOut')
// this.$store.commit('SET_PERMS', '')
this.$message({
type: 'success',
message: '退出成功!'
})
setTimeout(() => {
location.reload() // 强制刷新
}, 1000)
}).catch(() => {
this.$message({
type: 'info',
message: '已取消退出'
})
})
},