vue项目实现用户登录 以及携带token

14,136

调取登录接口 (首先明确一下要做到事情)

在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:

  1. 第一次登录的时候,前端调后端的登陆接口,发送用户名和密码
  2. 后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token
  3. 前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面
  4. 前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面
  5. 每次调后端接口,都要在请求头中加token
  6. 后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401
  7. 如果前端拿到状态码为401,就清除token信息并跳转到登录页面
  8. 调取登录接口成功,会在回调函数中将token存储到localStorage和vuex中

一、前期准备

页面模板

<template>  
    <div>    
        <input type="text" v-model="loginForm.username" placeholder="用户名"/>    
        <input type="text" v-model="loginForm.password" placeholder="密码"/>    
        <button @click="login">登录</button>  
    </div>
</template>

逻辑实现

export default {  
    data() { 
        return {
          loginForm: { 
               username: "",
               password: "",
          },    
        };  
     },  
    methods: { 
       ...mapMutations(["changeLogin"]),
       login() {
          let _this = this;

          /////判读账号密码是否输入,没有则alert 出来
          if (this.loginForm.username === "" || this.loginForm.password === "") {
            alert("账号或密码不能为空");      
          } else { 
             this.axios({          
                method: "post",
                url: "/user/login",
                data: _this.loginForm,
              })
                .then((res) => {
                    console.log(res.data);
                    _this.userToken = "Bearer " + res.data.data.body.token;

                    // 将用户token保存到vuex中 
                   _this.changeLogin({   
                       Authorization: _this.userToken,
                    });          
                   _this.$router.push("/home");
                    alert("登陆成功");     
                 })        
                 .catch((error) => { 
                   alert("账号或密码错误");   
                   console.log(error);
                  });
               }    
            },  
          },
};

3.在store文件夹下的index.js 添加 token

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);
const store = new Vuex.Store({  
    state: {    // 存储token    
        Authorization: localStorage.getItem('Authorization') ? localStorage.getItem('Authorization') : ''  
    },  
    mutations: {    // 修改token,并将token存入localStorage    
        changeLogin (state, user) {      
            state.Authorization = user.Authorization;      
            localStorage.setItem('Authorization', user.Authorization);    
        }  }});
    export default store;

二,配置 路由导航守卫

router文件夹下的index.js

import Vue from 'vue';
import Router from 'vue-router';
import login from '@/components/login';
import home from '@/components/home';Vue.use(Router);

const router = new Router({  
    routes: [   
            {      path: '/',      redirect: '/login'    },
            {      path: '/login',      name: 'login',      component: login    },
            {      path: '/home',      name: 'home',      component: home    }  ]});
           // 导航守卫
           // 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
            router.beforeEach((to, from, next) => { 
             if (to.path === '/login') {    next();  } 
             else {    let token = localStorage.getItem('Authorization');    
             if (token === 'null' || token === '')
             {      next('/login');    } 
             else {      next();    }  
             }
});
export default router;

三、请求头加token 在 main.js中添加

// 添加请求拦截器,在请求头中加token
axios.interceptors.request.use(  config => {    
    if (localStorage.getItem('Authorization'))
     {      
        config.headers.Authorization = localStorage.getItem('Authorization');    
     }    
    return config;  },  
    error => {    return Promise.reject(error);  
});

token的过期可以自定义

四、如果前端拿到状态码为401,就清除token信息并跳转到登录页面

localStorage.removeItem('Authorization'); this.$router.push('/login');