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();
    }
  }
});