使用 axios 拦截器时,API 调用循环出现 401 错误

时间:2021-04-02 14:03:00

标签: vue.js axios vuex interceptor

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

axios.js


    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 存储文件,我创建了一个刷新函数来执行刷新。

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);
          });
      });
    },
  },
});

以下是受保护数据的查看文件。 关于.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);
      });
  },

1 个答案:

答案 0 :(得分:0)

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

例如:

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