美文网首页
前后端分离实现JWT Token登录验证和状态保持,Vue代码

前后端分离实现JWT Token登录验证和状态保持,Vue代码

作者: 橙子只过今天 | 来源:发表于2021-02-06 10:41 被阅读0次

    参考自文章

    springboot+vue实现token验证

    Springboot+Vue前后端分离实现token登录验证和状态保存

    阮一峰——JSON Web Token 入门教程


    1. 后端Springboot

    2. 前端Vue

    目录结构

    image

    2.1 登录页的login方法:获取token并存储在localStorage中(view/login.vue)

    login() { 
    
        // 从用户输入中获取name和password,从user.js中引入封装的Login方法
    
          Login(this.users.name,this.users.password).then(res => {
    
              console.log(res)
    
              // 请求失败
    
              if(!res.data){
    
                alert("用户名或密码错误");
    
                return
    
              }
    
              const token = res.data.token;
    
              const user = res.data.user;
    
              /*存储到ls*/
    
              localStorage.setItem('eleToken',token);
    
              /*解析token中的信息*/
    
              const decoded = jwt(token);
    
              /*存储至vuex*/
    
              this.$store.dispatch("setLogin",!this.isEmpty(decoded))  //decoded空,函数返回真,取反假
    
              this.$store.dispatch("setUser",user)
    
              /*跳转*/
    
              this.$router.push('/home');
    
            })
    
            .catch(err => {
    
              console.log(err)
    
            });
    
        },
    
        isEmpty(value){
    
          return(
    
              value ===undefined || value ===null ||
    
              (typeof  value === "object" && Object.keys(value).length ===0) ||
    
              (typeof value ==="string" && value.trim().length ===0)
    
          );
    
        },
    

    2.2 路由守卫判断是否存在token,存在时正常访问,不存在时要求登录(router/index.js)

    /*路由守卫   根据登录获得token*/
    
    router.beforeEach((to,from,next) =>{
    
      const isLogin = localStorage.eleToken ? true :false ;
    
      if(to.path ==="/login" || to.path ==="/register"){
    
        next();
    
      }else{
    
        isLogin ? next() :next("/login")   /*真跳转  假登录*/
    
      }
    
    })
    

    2.3 axios请求拦截和响应拦截(network/request.js)

    import axios from 'axios'
    
    import { Loading } from 'element-ui';   /*elementUI的loading*/
    
    import { Message } from 'element-ui';   /*elementUI消息提醒*/
    
    import router from '../router/index';
    
    let loading;
    
    function startLoading () {
    
      loading = Loading.service({    /*在需要调用时:*/
    
        lock: true,
    
        text: '拼命加载中...',
    
        background: 'rgba(0,0,0,0,7)'
    
      });
    
    }
    
    function endLoading () {
    
      loading.close();
    
    }
    
    export function request(config){
    
      const instance = axios.create({
    
        baseURL:'http://localhost:8888/day07/',
    
        timeout:5000
    
      })
    
      //请求拦截
    
      instance.interceptors.request.use(config => {
    
        //加载动画
    
        //startLoading();
    
        /*判断token存在   登录拦截*/
    
        if(localStorage.eleToken){
    
          /*设置统一的header*/
    
          config.headers.Authorization  = localStorage.eleToken;
    
        }
    
        return config;
    
      },error => {
    
        return Promise.reject(error);
    
      });
    
      //响应拦截
    
      axios.interceptors.response.use(Response => {
    
          //结束加载动画
    
          //endLoading();
    
          return Response;
    
        },error => {
    
        //错误提醒
    
        //endLoading();
    
        Message.error(error.response.data);
    
        /*获取错误状态码*/
    
        const  { status } =error.response;
    
        if(status == 401){
    
          Message.error("token失效,重新登录");
    
          /*清楚token*/
    
          localStorage.removeItem('eleToken');
    
          /*跳转登录*/
    
          router.push('/login')
    
        }
    
        return Promise.reject(error);
    
      })
    
      // 发送真正网络请求并返回
    
      return instance(config)
    
    }
    

    2.4 页面刷新时重新判断token是否存在或过期,并将需要数据保存到vuex中(App.vue)

    <script>
    
    import jwt from 'jwt-decode';
    
    import {findOneUserById} from './network/user'
    
    export default {
    
      name:'App',
    
      created(){   /*在根组件进行判断,否则刷新就没了*/
    
        this.initData()
    
      },
    
      methods: {
    
        // 有token时初始化数据
    
        initData(){
    
          if (localStorage.eleToken){
    
            const decoded = jwt(localStorage.eleToken);
    
            let _this = this;
    
            // 需完善,其它组件初始化获取vuex中的user数据时,若请求未完成user为undefined
    
            findOneUserById(decoded.aud).then(res => {
    
              console.log(res)
    
              // token已过期
    
              if(res.data.code == 401){
    
                /*存储至vuex*/
    
                localStorage.removeItem('eleToken')
    
                _this.$store.dispatch("setLogin",false)
    
              }else{
    
                _this.$store.dispatch("setUser",res.data)
    
                /*存储至vuex*/
    
                _this.$store.dispatch("setLogin",!this.isEmpty(decoded))
    
              }
    
            }).catch(err=>{
    
              console.log(err)
    
            })
    
          }
    
        },
    
        isEmpty(value){
    
            return(
    
                value ===undefined || value ===null ||
    
                (typeof  value === "object" && Object.keys(value).length ===0) ||
    
                (typeof value ==="string" && value.trim().length ===0)
    
            );
    
        }
    
      }
    
    }
    
    </script>
    

    2.5 vuex中保存登录状态和登录用户信息(store/index.js)

    import Vue from 'vue'
    
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const types ={
    
      SET_LOGIN: 'SET_LOGIN',
    
      SET_USER: 'SET_USER',
    
    };
    
    export default new Vuex.Store({
    
      state: {
    
        isLogin:false,
    
        user:{}
    
      },
    
      mutations: {
    
        [types.SET_LOGIN](state,isLogin){      /*设置是否授权*/
    
          if(isLogin) state.isLogin = isLogin;
    
          else state.isLogin = false;
    
        },
    
        /*类型,参数*/
    
        [types.SET_USER](state,user){
    
          if (user) state.user = user;
    
          else state.user = {};
    
        },
    
      },
    
      actions: {
    
        setLogin:( {commit},isLogin) =>{
    
          commit(types.SET_LOGIN,isLogin);
    
        },
    
        setUser:({commit},user) =>{
    
          commit(types.SET_USER,user);
    
        }
    
      },
    
      modules: {
    
      }
    
    })
    

    相关文章

      网友评论

          本文标题:前后端分离实现JWT Token登录验证和状态保持,Vue代码

          本文链接:https://www.haomeiwen.com/subject/alfztltx.html