使用axios拦截器时,API调用循环出现401错误 [英] When using axios interceptors, API calls are looping for 401 error

查看:363
本文介绍了使用axios拦截器时,API调用循环出现401错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在VueJs中使用拦截器来使用axios请求刷新令牌.我已经用拦截器编写了一些逻辑,并分发了存储.当令牌到期并且我重新加载页面时,将尝试无限次地形成api post调用.要停止它,我必须关闭浏览器或注销并刷新页面.而另一个错误是"import/no-cylce"尝试导入商店时在我的axios.js文件上.下面是我的代码,任何建议都是有帮助的,谢谢.

I am trying to use interceptors in VueJs to request refresh token using axios. I have written some logic with interceptors and dispatch to store. When token expires and i reload the page, api post call is attempted infinitely forming a loop.to stop it i have to close the browser or logout and refresh the page. And the other error is "import/no-cylce" on my axios.js file when trying to import store. Below is my code, any suggestions are helpful, thanks.


    import axios from 'axios';
    // eslint-disable-next-line import/no-cycle
    import store from '@/store';
    // eslint-disable-next-line import/no-cycle
    
    // axios.defaults.headers.common.Authorization = `Bearer ${sessionStorage.getItem('accessToken')}`;
    
    const getAPI = axios.create({
      baseURL: 'http://127.0.0.1:5000',
    });
    getAPI.interceptors.response.use(undefined, (error) => {
      if (error.config && error.response.status === 401) {
        const result = 'test interceptor';
        console.log(result);
        store.dispatch('refreshToken')
          // eslint-disable-next-line camelcase
          .then((access_token) => {
            axios.request({
              headers: { Authorization: `Bearer ${this.$store.state.accessToken}` },
            });
            console.log(access_token);
          });
      }
    });
    // eslint-disable-next-line import/prefer-default-export
    export { getAPI };

下面是Vuex存储文件,我创建了一个刷新功能来执行刷新.

Below is Vuex store file, I created a refresh function to perform refresh.

import Vue from 'vue';
import Vuex from 'vuex';
// eslint-disable-next-line import/no-cycle
import { getAPI } from '@/axios';
// eslint-disable-next-line camelcase

Vue.use(Vuex);
export default new Vuex.Store({
  state: {
    // accessToken: JSON.parse(localStorage.getItem('access_token')) || null,
    // refreshToken: JSON.parse(localStorage.getItem('refresh_token')) || null,
    accessToken: localStorage.getItem('access_token') || null,
    refreshToken: localStorage.getItem('refresh_token') || null,
    APIData: '',
  },
  getters: {
    loggedIn(state) {
      return state.accessToken != null;
    },
  },
  mutations: {
    // eslint-disable-next-line camelcase
    updateLocalStorage(state, { access_token, refresh_token }) {
      // localStorage.setItem('accessToken', JSON.stringify(access_token));
      // localStorage.setItem('refreshToken', JSON.stringify(refresh_token));
      localStorage.setItem('access_token', access_token);
      localStorage.setItem('refresh_token', refresh_token);
      // eslint-disable-next-line camelcase
      state.accessToken = access_token;
      // eslint-disable-next-line camelcase
      state.refreshToken = refresh_token;
    },
    // eslint-disable-next-line camelcase
    updateAccessToken(state, access_token) {
      // eslint-disable-next-line camelcase
      state.accessToken = access_token;
    },
    destroyToken(state) {
      state.accessToken = null;
      state.refreshToken = null;
    },
  },
  actions: {
    userLogin(context, credentials) {
      return new Promise((resolve, reject) => {
        getAPI.post('/login', {
          email: credentials.email,
          password: credentials.password,
        })
          .then((response) => {
            context.commit('updateLocalStorage', { access_token: response.data.access_token, refresh_token: response.data.refresh_token });
            resolve();
            console.log('\'access token\'', response.data.access_token);
            console.log('\'refresh token\'', response.data.refresh_token);
            // console.log(context.state.accessToken);
            // console.log(context.state.refreshToken);
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
    userLogout(context) {
      if (context.getters.loggedIn) {
        // context.commit('updateLocalStorage', null);
        context.commit('destroyToken');
      }
    },
    refreshToken(context) {
      return new Promise((resolve, reject) => {
        console.log(context.state.refreshToken);
        getAPI.post('/refresh', {
          // refresh_token: context.state.refreshToken,
          headers: { Authorization: `Bearer ${context.state.refreshToken}` },
        })
          .then((response) => {
            console.log('New access token granted');
            context.commit('updateAccessToken', response.data.access_token);
            console.log(context.state.accessToken);
            resolve(response.data.access_token);
          })
          .catch((error) => {
            console.log('\'error in refresh:\'', error);
            reject(error);
          });
      });
    },
  },
});

下面是受保护数据的查看文件.About.vue

Below is view file for protected data. About.vue

 created() {
    getAPI.get('/userList', {
      // eslint-disable-next-line no-undef
      headers: { Authorization: `Bearer ${this.$store.state.accessToken}` },
    },
    console.log(`Bearer ${this.$store.state.accessToken}`))
      .then((response) => {
        this.$store.state.APIData = response.data;
        console.log(response.data);
      })
      .catch((error) => {
        console.log(error);
      });
  },

推荐答案

此外,我更早收到此错误.我使用了 axiosAuth 而不是 axio

Also, i'm getting this error earlier. I used axiosAuth instead of axio

ex-:

 const getAPI = axiosAuth.create({
      baseURL: 'http://127.0.0.1:5000',
    });

这篇关于使用axios拦截器时,API调用循环出现401错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆