1、什么是Token
Token是服务端生成的一串字符串,作为客户端进行请求时辨别客户身份的的一个令牌。当用户第一次登录后,服务器生成一个Token便将此Token返回给客户端。以后客户端的每次请求带上token,服务端就能辨别是哪一个用户。
也可以将token比喻成一把钥匙,每当用户来访问服务器的时候就带上这把钥匙,然后去解服务器上的锁。如果锁解开了,那么用户就是登陆了,如果锁解不开,那么则提示用户未登录或登录已经失效。
2、token的应用流程
1)用户第一次登录时,向服务器发起请求。服务器根据账号和密码判断是否登录成功,如果是首次登录,服务器会生成一个新的token,并保存到数据库,数据库中存储了每个用户对应的token。最后服务器会把这个token返回给客户端。
2)用户登录成功后,客户端将接收到的token存储到浏览器(localStorage或者sessionStorage)和vuex上。
3)设置请求头,将token放在请求头上,并让客户端的每次请求都带上token。
4)用户的每次请求,服务器都能根据token辨别出是哪个用户。每个用户都有一个不同的token。当然,为了再安全一点,我们还可以让用户每次把钥匙(token)发给我们的时候,再给他一把新钥匙(token),也就是说钥匙(token)只能使用一次,被劫持了咱也不怕。
3、代码实现
1)使用node.js搭建的服务器上处理登录请求,并返回token。token的生成是由后端生成的,这里就不深入到token的生成了。
//模拟admin该用户第一次登录时,返回一个新的token
router.post('/login',function (request,response){
if(userName == 'admin' && userPwd == '123'){ //当账号密码正确
//token的生成需要引入一个可以生成token的库jsonwebtokens,这里只是模拟,就不生成了,直接给一个死数据
let token = 'werty1234';
response.send({code:200,data:token})
}else {
response.send({code:400,msg:'账号或密码不正确'})
}
})
2)在vuex上做处理,将接收到的token存储到state和浏览器中
store/index.js
export default new Vuex.Store({
state: {
token: sessionStorage.getItem('token') ? sessionStorage.getItem('token') : ''
},
mutations: {
//登录成功,存储信息到浏览器和state中
loginSuccess(state, data) {
state.token= data.token;
sessionStorage.setItem('token', state.token);
}
},
actions: {
loginSuccess({commit}, data) {
commit('loginSuccess', data)
}
}
})
3)设置请求头
main.js
//设置请求头
Axios.defaults.headers.common['token'] = store.state.token;
//每次发起请求时,判断是否有token,有则带上token
Axios.interceptors.request.use(
config => {
if(sessionStorage.getItem('token')){
config.headers.common['token'] = sessionStorage.getItem('token');
}
return config;
},
error => {
return Promise.reject(error);
}
);
4)登录成功,存储token
this.$axios.post('服务器接口ip:端口/login',{
userName:this.loginForm.username,
userPwd:this.loginForm.pwd
}).then(res=>{
if(res.data.code == 200){ //状态码为200,表示登录成功
var token = res.data.data;
// 将接收到的token存储到vuex中
this.$store.dispatch('loginSuccess',{token:token});
//跳转其他页面
this.$router.push('/index').catch(err=>{
console.log(err)
});
}else{
this.$message.error(res.data.msg);
}
}).catch(err=>{
this.$message.error(err);
})
当用户登录成功后,已经完成了token的存储和请求头的设置。当该用户再向服务器发起请求后,都会带上这个token。服务器根据token识别用户身份,再对该用户的请求作出响应。
5)最后也可以设置一个全局守卫,通过判断浏览器是否存储了token来判断用户是否登录。没有则跳到登录界面
main.js
//路由拦截
router.beforeEach((to,from,next)=>{
if(to.name == 'login'){ //如果是进入登录界面
next();
}else{ //进入其他页面
let token = sessionStorage.getItem('token');
if(token == '' || token == null){
next('/login');
}else{
next();
}
}
});