vue下axios拦截器token刷新机制的实例代码

//创建http.js文件,以下是具体代码:

//引入安装的axios插件
import axios from 'axios'
import router from '@/router';
import Vue from 'vue'
const qs = require("qs");
let _this = new Vue();
let isLock = false;
let refreshSubscribers = [];
//判断token是否过期
function isTokenExpired(token) {
 let expires_time = JSON.parse(token).expires_time;
 let curentTime = new Date().getTime();
 if (curentTime >= expires_time) {
  return true;
 } else {
  return false;
 }
}
//获取Token对象
function getToken() {
 return localStorage.getItem("token");
}
//push所有请求到数组中
function subscribeTokenRefresh(cb) {
 refreshSubscribers.push(cb)
}

//刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)
function onRrefreshed(token) {
 refreshSubscribers.map(cb => cb(token))
}
//刷新token
function refreshToken(config, token, resolve, reject) {
 let data = { refresh_token: JSON.parse(token).refresh_token };
 axios({
  method: "post",
  url: "xxxxxx/refreshToken",//刷新token的接口
  headers: {
   "Content-Type": "application/x-www-form-urlencoded",
   "Authorization": "Basic b3JkZXItc2VydmVyOjEyMzQ1Ng=="
  },
  data: qs.stringify(data)
 }).then(res => {
  isLock = false;//释放锁
  if (res.data.code === 101) {
   _this.$message.error('登录状态已失效,请重新登录。');
   localStorage.removeItem("token");
   router.push({
    path: "/login"
   });
   return;
  }

  let expires_time = new Date().getTime() + parseInt(res.data.data.expires_in * 0.8) * 1000;
  let token = JSON.parse(localStorage.getItem("token"));
  token.expires_time = expires_time;
  token.access_token = res.data.data.access_token;
  localStorage.setItem("token", JSON.stringify(token));

  config.headers.Authorization = 'Bearer ' + res.data.data.access_token;
  resolve(config);
  //执行数组里的函数,重新发起被挂起的请求
  onRrefreshed(res.data.data.access_token)
  //清空数组中保存的请求
  refreshSubscribers = []
 }).catch(err => {
  return err;
 });
}

function request(newOptions, resolve, reject) {
 axios({
  method: newOptions.method,
  url: newOptions.url,
  data: newOptions.type == "form" ? qs.stringify(newOptions.data) : newOptions.data,
  headers: newOptions.headers
 }).then(res => {
  if (res.status == 200) {
   //这里我们只需要获取返回的data中的数据即可
   resolve(res.data);
  } else {
   reject(res.data);
  }
 }).catch(err => {
  reject(err);
  _this.$message.error('服务异常!');
 })
}

axios.interceptors.request.use(
 config => {
  let token = getToken();
  if (token) {
   //判断token是否过期,如果过期请求刷新token
   if (isTokenExpired(token)) {
    //判断当前是否正在请求刷新token
    if (!isLock) {
     isLock = true;//isLock设置true,锁住防止死循环。
     //使用Promise等待刷新完成返回配置信息
     let refresh = new Promise((resolve, reject) => {
      refreshToken(config, token, resolve, reject);
     })
     return refresh;

    } else {
     //判断当前url是否是刷新token的请求地址,如果是直接下一步。
     if (config.url.indexOf('/logined/refreshToken') === -1) {
      //把请求(token)=>{....}都push到一个数组中
      let retry = new Promise((resolve, reject) => {
       //(token) => {...}这个函数就是回调函数
       subscribeTokenRefresh((token) => {
        config.headers.Authorization = 'Bearer ' + token
        //将请求挂起
        resolve(config)
       })
      })
      return retry

     } else {
      return config;
     }
    }

   } else {
    return config;
   }

  } else {
   return config;
  }
 }, error => {
  return Promise.reject(error);
 });
const http = options => {
 return new Promise((resolve, reject) => {
  const defaultOptions = {
   type: "json"
  };
  const newOptions = {
   ...defaultOptions,
   ...options
  };
  //headers默认传递json格式数据,这里也可以设置token,每次调用都会携带
if (localStorage.getItem("token")) {
    newOptions.headers = {
     // 'Authorization': 'Basic b3JkZXItc2VydmVyOjEyMzQ1Ng==',
     'content-Type': newOptions.type == 'form' ? 'application/x-www-form-urlencoded;charset=UTF-8' : 'application/json;charset=UTF-8',
     'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem("token")).access_token,
     ...newOptions.headers
    };
   } else {
    newOptions.headers = {
     'content-Type': newOptions.type == 'form' ? 'application/x-www-form-urlencoded;charset=UTF-8' : 'application/json;charset=UTF-8',
     ...newOptions.headers
    };
   }
  request(newOptions, resolve, reject);
 })
};

//设置请求超时
axios.defaults.timeout = 30000
export default http

//在main.js下面挂载 http.js文件
import http from '@/utils/http.js';
Vue.prototype.http = http;

//登录保存token信息接口

this.http({
      method: "post",
      url: "/xxxxx/user",
      type: "form",
      headers: { Authorization:"Basicb3JkZXItc2VydmVyOjEyMzQ1Ng==" },
      data: {}
     }).then(function(res) {
        let expires_time =
         new Date().getTime() +
         parseInt(res.data.token.expires_in * 0.8) * 1000;
         let token = res.data.token;
         token.expires_time = expires_time;
        localStorage.setItem("token", JSON.stringify(token));

      }).catch(function(err) {
       console.log(err);
      });        

//退出清空token
this.http({
    method: "get",
    url: "/xxxxx/logout",
    data: {}
   }).then(function(res) {
 localStorage.removeItem("token");
  }).catch(function(err) {
     console.log(err);
    });

总结

以上所述是小编给大家介绍的vue下axios拦截器token刷新机制的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • 在vue中获取token,并将token写进header的方法

    需要准备的东西:Vue+axios+Vuex+Vue-router 1.在login.vue中通过发送http请求获取token //根据api接口获取token var url = this.HOST + "/session"; this.$axios.post(url, { username: this.loginForm.username, password: this.loginForm.pass }).then(res => { // console.log(res.d

  • vue的token刷新处理的方法

    第一次接触token处理,初来乍到,说错的地方还请各位多多指教. token身份验证机制 客户端登录请求成功后,服务器将用户信息(如用户id)使用特殊算法加密后作为验证的标志发送给用户(即token),当用户下次发起请求时,会将这个token捎带过来,服务器再将这个token通过解密后进行验证,通过的话,则向客户端返回请求的数据:反之,则请求失败. token优点 它是无状态的,且服务器不用像传统的身份认证(session)那样需要保存会话信息,减轻了服务器的压力. vue的token刷新处理

  • Vue项目报错:Uncaught SyntaxError: Unexpected token <

    遇到问题: 今天做一个 VUE 的项目,在引入第三方依赖的 JS 文件时,遇到了一个问题: 控制台的提示:Uncaught SyntaxError: Unexpected token < 按照提示进入文件,再看如下图: 仔细看了看 index.html 文件,发现原本我的 JS 文件是放在 /src/utils 文件夹下的,但引入 /src 和 /static 的文件是有区别的. 解决方案: 解决办法是将第三方依赖的 JS 文件放到 /static/utils 目录下,引入路径也改成:<scr

  • vue生成token并保存到本地存储中

    首先回顾一下token: token认证是RESTFUL.api的一个很重要的部分,通过token认证和token设置,后端会有一个接口传给前台: http://localhost/yiiserver/web/index.php/token?client_appid=aaa&client_appkey=bbb 其实就是向用户表里去生成一个token 这里的client_id相当于用户名,client_key相当于密码,这样后台会生成一个client_token,我们需要把这个token保存到客户

  • vue 实现axios拦截、页面跳转和token 验证

    第一步: 路由 多添加一个自定义字段 requireAuth path: '/repository', name: 'repository', meta: { requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的 }, component: Repository 第二步: router.beforeEach((to, from, next) => { if (to.meta.requireAuth) { // 判断该路由是否需要登录权限 if (store.sta

  • vue下axios拦截器token刷新机制的实例代码

    //创建http.js文件,以下是具体代码: //引入安装的axios插件 import axios from 'axios' import router from '@/router'; import Vue from 'vue' const qs = require("qs"); let _this = new Vue(); let isLock = false; let refreshSubscribers = []; //判断token是否过期 function isToken

  • Vue中axios拦截器如何单独配置token

    在了解到cookie.session.token的作用后学习token的使用 cookie cookie是随着url将参数发送到后台,安全性最低,并且大小受限,不超过4kb左右,它的数据保存在客户端 session session数据保存在服务端,在内存中开辟空间存储数据,session文件名即sessionID保存在cookie内,随cookie传送到服务端后在服务端匹配session文件 token token是服务端的一种算法,如果登录成功,服务端就会根据算法生成一个字符串,将字符串传递回

  • 利用spring的拦截器自定义缓存的实现实例代码

    本文研究的主要是利用spring的拦截器自定义缓存的实现,具体实现代码如下所示. Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.本文利用Memcached 的实例和spring的拦截器实现缓存自定义的实现.利用拦截器读取自定义的缓存标签,key值的生成策略. 自定义的Cacheable package com.jeex.sci; @Target(ElementT

  • vue 对axios get pust put delete封装的实例代码

    axios.js import axios from 'axios'; import Qs from 'qs'; import {Message} from 'element-ui'; axios.defaults.baseURL = "/api"; // 设置请求超时时间 axios.defaults.timeout = 30000; // 设置post请求头 axios.defaults.headers.post['Content-Type'] = 'application/jso

  • Vue 前端实现登陆拦截及axios 拦截器的使用

    该项目是利用了Github 提供的personal token作为登录token,通过token访问你的Repository List.通过这个项目学习如何实现一个前端项目中所需要的 登录及拦截.登出.token失效的拦截及对应 axios 拦截器的使用. 准备 你需要先生成自己的 Github Personal Token( 生成Token). Token 生成后 访问 Demo,即可查看你的Repository List. 项目结构 ├── README.md ├── dist // 打包构

  • 详解Vue中使用Axios拦截器

    需求是拦截前端的网络请求和相应. 废话不多说,直接上干货. 我用的是vue-cli3所以这个config文件是我自己创建的. 先介绍env.js //根据不同的环境更改不同的baseUrl let baseUrl = ''; //开发环境下 if (process.env.NODE_ENV == 'development') { baseUrl = ''; } else if (process.env.NODE_ENV == 'production') { baseUrl = '生产地址'; }

  • vue+axios 拦截器实现统一token的案例

    需求 要想统一处理所有http请求和响应,就得用上 axios 的拦截器.通过配置 http response inteceptor ,当后端接口返回 401 Unauthorized(未授权) ,让用户重新登录. 通过这个项目学习如何实现一个前端项目中所需要的 登录及拦截.登出.token失效的拦截及对应 axios 拦截器的使用. 代码如下: const instance = axios.create({ baseURL: 'http://www.laravel5.5.com/api/',

  • vue 导航守卫和axios拦截器有哪些区别

    在Vue项目中,有两种用户登录状态判断并处理的情况,分别为:导航守卫和axios拦截器. 一.什么是导航守卫? vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航.(在路由跳转时触发) 我们主要介绍的是可以验证用户登录状态的全局前置守卫,当一个导航触发时,全局前置守卫按照创建顺序调用.守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中. const router = new VueRouter({ ... })   router.beforeEac

  • vue axios拦截器常用之重复请求取消

    引言 上一篇介绍了axios的简单封装,知道了axios拦截器的应用场景和方法,今天来看一下对于响应时间过长且请求次数过高的情况拦截器如何处理. 取消请求的方法 Axios使用内部提供的CancelToken来取消请求 官网示例1:用CancelToken.source工厂方法创建 cancel token,像这样 const CancelToken = axios.CancelToken; const source = CancelToken.source(); axios.get('/use

  • Vue声明式导航与编程式导航及导航守卫和axios拦截器全面详细讲解

    目录 一.声明式导航&编程式导航 二.导航守卫 三.axios拦截器 一.声明式导航&编程式导航 1. 声明式导航:以超链接方式实现的页面跳转,就是声明式导航 < a href=‘url’> 链接文本或图像 < /a > < router-link to=‘url’ > 链接文本或图像 < /router-link > 2. 编程式导航:通过javascript提供的api方法实现页面的跳转,就是编程式导航 location.href = ‘

随机推荐