关于解决token过期失效问题「建议收藏」

关于解决token过期失效问题「建议收藏」关于解决token过期失效问题,用户对token无感知(实现免登陆)一、先认识下token二、整体思路三、实现步骤1.理清各个文件作用2.路由导航守卫3.封装localStorage方法4.vuex5.封装axios实现请求拦截器和响应拦截器(重点部分)四、小结一、先认识下token二、整体思路三、实现步骤1.理清各个文件作用2.路由导航守卫设置用户有无token访问主页,并且登录成功回到目标页importVuefrom’vue’importVueRouterfrom’v

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、先认识下token

在这里插入图片描述

二、整体思路

在这里插入图片描述

三、实现步骤

1.理清各个文件作用

在这里插入图片描述

2.路由导航守卫

设置用户有无token访问主页,并且登录成功回到目标页

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store/index.js'
Vue.use(VueRouter)
const router = new VueRouter({ 
   
  routes
})
// 路由导航守卫
router.beforeEach((to, from, next) => { 
   
  if (to.path.startsWith('/user')) { 
   
    // 判断token
    if (store.state.tokenInfo.token) { 
   
      next()
    } else { 
   
      next({ 
   
        path: '/login',
        query: { 
   
          // 登录成功回到目标页
          backto: to.fullPath // fullPath 会拿到路由后面的查询字符串
        }
      })
    }
  } else { 
   
    next()
  }
})
export default router
3.封装localStorage方法

目的在vuex中调用

/ 封装模块 使用localStorage实现持久化 只是进行保存
// 从localStorage中取出一项数据 名字叫name
export const getItem = name => { 
   
  return JSON.parse(localStorage.getItem(name))
}
// 向localStorage中设置一项数据 名字为name里面设置值为obj
export const setItem = (name, obj) => { 
   
  localStorage.setItem(name, JSON.stringify(obj))
}
// 删除
export const removeitem = name => { 
   
  localStorage.removeItem(name)
}
4.vuex
import Vue from 'vue'
import Vuex from 'vuex'
import { 
    setItem, getItem } from '@/utils/storage.js'
Vue.use(Vuex)

export default new Vuex.Store({ 
   
  state: { 
   
    // 保存公共数据
    tokenInfo: getItem('tokenInfo') || { 
   }
  },
  mutations: { 
   
    mSetTokenInfo (state, tokenObj) { 
   
      state.tokenInfo = tokenObj
      // 因为刷新会丢失所以进行持久化 调用storage方法
      setItem('tokenInfo', tokenObj)
    }
  },
  // -------------------此次重点---------------------------------------------------------
  // 只跟新token 不跟新响应拦截器里面的refreshToken
  mUpdateToken (state, newToken) { 
   
    state.tokenInfo.token = newToken
    setItem('tokenInfo', state.tokenInfo)
  },
  actions: { 
   
  },
  modules: { 
   
  }
})
5.封装axios 实现请求拦截器和响应拦截器(重点部分)

关于axios拦截器 可参考官方文档
(点我)axios拦截器官方跳转链接

/* 对axios进行二次封装 请求拦截器增加token 响应拦截器处理大数据 */
import store from '@/store/index.js'
import axios from 'axios'
import JSONbig from 'json-bigint' // 引入大数字包
import router from '@/router/index.js'
/* 以前写法: axios.defaults.baseURL = 'XXX' 自定义写法:const xxx = axios.create({}) 一个项目中可能有不同的基地址 就要用自定义写法设置不同的基地址 */
const instance = axios.create({ 
   
  baseURL: 'http://ttapi.research.itcast.cn',
  transformResponse: [function (data) { 
   
    if (data === '') { 
   
      return false
    }
    try { 
   
      // 如果没有遇到错误,就返回 JSONbig处理之后的数据
      return JSONbig.parse(data)
    } catch (err) { 
   
      console.log('JSONbig转换出错', err)
      return data
    }
  }]
})
// 在instance上添加请求拦截器 补充请求头token信息
instance.interceptors.request.use(function (config) { 
   
  // 从vuex中取出token
  const token = store.state.tokenInfo.token
  // 如果有token则 添加到headers中
  if (token) { 
   
    config.headers.Authorization = `Bearer ${ 
     token}`
  }
  return config
}, function (error) { 
   
  return Promise.reject(error)
})
//------------------------这里处理token过期--------------------------------------------
// 添加响应拦截器 处理401 token过期
instance.interceptors.response.use(function (response) { 
   
  return response
}, async function (error) { 
   
  // 如果是401错误 则做以下错误
  if (error.response.status === 401) { 
   
    // 从vuex中取出token
    const refreshToken = store.state.tokenInfo.token
    // 是否有refreshToken
    if (refreshToken) { 
   
      // 用refresh_token 重发请求 再次取回一个有效期的
      try { 
   
       // 注意这里重新发请求要用axios 不能用封装的instance url地址是根据接口文档写的
        const { 
    data: res } = await axios({ 
   
          method: 'PUT',
          url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',
          headers: { 
   
            Authorization: `Bearer ${ 
     refreshToken}`
          }
        })
        // 定义赋值新的token
        const newToken = res.data.token
        // 跟新vuex
        store.commit('mUpdateToken', newToken)
        // 再发请求
        return instance(error.config)
      } catch { 
     // 如果没有拿到新的token 
        // 回登录页
        router.push({ 
   
          path: '/login',
          query: { 
   
            // currentRoute表示当前路由对象
            backto: router.currentRoute.fullPath
          }
        })
      }
    } else { 
      // 如果没有refreshToken
      router.push({ 
   
        path: '/login',
        query: { 
   
          backto: router.currentRoute.fullPath
        }
      })
    }
  } else { 
     // 如果不是401错误
    return Promise.reject(error)
  }
})
export default instance

四、小结

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/194603.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 镁光硬盘测试软件,镁光固态硬盘评测[通俗易懂]

    镁光硬盘测试软件,镁光固态硬盘评测[通俗易懂]镁光M500DC企业级120G固态硬盘前言近期NAND市场为值友所喜闻乐见,3DTLC大幅度跳水,越来越多厂商加入瓜分市场的行列,加之QLC即将大量问世,M.2接口的SSD即将冲破1元1G的大关。在此情景下,SATA口SSD在各类值得买爆款里随便挑一款不失为一个很好的选择,然而对于不少值友,TLC的寿命、写入放大、全盘模拟SLC导致后期掉速、黑白片拆机ufs等诸多问题的存在,终究无法满足其苛刻的…

    2022年6月22日
    42
  • datagridview 自定义格式_word自定义表格

    datagridview 自定义格式_word自定义表格publicclassMyGrideViewextendsGridView{publicMyGrideView(Contextcontext){super(context);}publicMyGrideView(Contextcontext,AttributeSetattrs){super(context,attrs)

    2022年9月24日
    0
  • 微信小程序如何实现支付功能?看官方文档头疼(使用云函数的方式操作)「建议收藏」

    先来个效果图^_^微信支付功能,个人公众号是没有办法进行开发支付功能的,需要是使用非个人公众号进行注册(如:营业执照等,可以去淘宝购买一个也行大概500左右)公众平台的配置可以参考文档,这里主要是微信官网注册非个体公众号的否需代码操作。(也就是和我们码农相关的操作了)耐心看下面操作,基本上就是复制下面的代码(整个操作也就一会,基础再差也就30分钟搞定支付)^_^1.创建微信小程序2.在微信小程中序创建云函数1).根目录下创建一…

    2022年4月18日
    320
  • ES6模板字符串`的引用

    ES6模板字符串`的引用传统的JavaScript语言,输出模板通常是这样写的(下面使用了jQuery的方法)。$(‘#result’).append(‘Thereare<b>’+basket.count+'</b>’+’itemsinyourbasket,’+'<em>’+basket.onSale+'</em>areonsale!’);上面这种写法相当繁琐不方便,ES6引入了模板字符串解决这个问题。

    2022年8月21日
    10
  • java 动态获取web应用的部署路径[通俗易懂]

    java 动态获取web应用的部署路径

    2022年1月27日
    38
  • i686和x86_64的区别

    i686和x86_64的区别i686的解释:i代表intel系列的cpu。386几乎适用于所有的x86平台,不论是旧的pentum或者是新的pentum-IV与K7系列的CPU等等,都可以正常的工作!那个i指的是Intel兼容的CPU的意思,至于386不用说,就是CPU的等级啦!i586就是586等级的计算机,那是哪些呢?包括pentum第一代MMXC…

    2022年6月7日
    141

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号