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

参考自文章

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: {

  }

})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容