简体   繁体   English

axios-auth-refresh 的问题

[英]Issue with axios-auth-refresh

I'm trying to implement refresh-token from react.我正在尝试从反应中实现刷新令牌。 I'm using this library axios-auth-refresh which seems to work very fine except for one API.我正在使用这个库 axios-auth-refresh,除了一个 API 之外,它似乎工作得很好。

// api.js
import Axios from "axios";
import Cookies from 'js-cookie'
import { TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME } from '../constants/constants';
import createAuthRefreshInterceptor from 'axios-auth-refresh';

const api = Axios.create({
    baseURL: process.env.REACT_APP_BACKEND_URL,
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    }
});

const refreshAuthLogic = async (failedRequest) => {
    const refresh_token = Cookies.get(REFRESH_TOKEN_COOKIE_NAME);
    // if(!refresh_token) return;
    console.log(refresh_token);
    const tokenRefreshResponse = await api.post('auth/createtoken', {
    }, {
        headers: {'Authorization': 'Bearer ' + refresh_token},
        validateStatus: () => true
    });
    console.log(tokenRefreshResponse);
    if(tokenRefreshResponse.data.statusCode === 401 || tokenRefreshResponse.data.statusCode === 403) {
        Cookies.remove(REFRESH_TOKEN_COOKIE_NAME);
        if(!window.location.href.includes('login')) {
            window.location.href = "http://localhost:3000/login";
        }
        return;
    }
    const access_token = tokenRefreshResponse.data.access_token;
    Cookies.set(TOKEN_COOKIE_NAME, access_token, { expires: 60 })
    api.defaults.headers.Authorization = `Bearer ${access_token}`
    failedRequest.response.config.headers['Authorization'] = 'Bearer ' + access_token;
}

// Instantiate the interceptor (you can chain it as it returns the axios instance)
createAuthRefreshInterceptor(api, refreshAuthLogic);

export default api;

The following api call does NOT repeat in case 401 is returned:如果返回 401,则以下 api 调用不会重复:

const fetchUsers = async () => {
    const { data } = await api.get(`users/`, {params: {tripUsers: true}}, {
      validateStatus: (status) => status !== 401 && status !== 403
    })
    setUsers(data);
  }

  useEffect(() => {
      fetchUsers();
  }, [])

The following api call DOES repeat in case 401 is returned:如果返回 401,则以下 api 调用会重复:

const fetchProfile = async () => {
        const { data } = await api.get(`/users/${user.userId}`, {}, {
            validateStatus: (status) => status !== 401 && status !== 403
        })

        const {statusCode, message} = data;
        console.log(data);
    
        if(!statusCode) {
            console.log(data);
            setState(data);
        }
    }

    useEffect(() => {
        fetchProfile();
    }, [])

Please help.请帮忙。

After spending some time on this issue, I decided to create a generic API caller rather than using axios interceptors or any other library.在这个问题上花了一些时间后,我决定创建一个通用的 API 调用程序,而不是使用 axios 拦截器或任何其他库。 Here's my generic axios API caller.这是我的通用 axios API 调用者。 It can still be improved, but the idea is to call the API again with a new token if the first token is expired.它仍然可以改进,但想法是如果第一个令牌已过期,则使用新令牌再次调用 API。

// api.js
import Axios from "axios";
import Cookies from 'js-cookie'
import { TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME } from '../constants/constants';

const api = Axios.create({
    baseURL: process.env.REACT_APP_BACKEND_URL,
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    }
});

export const callApi = async (method, url, params, other) => {
    const validateStatus = 
        url === 'auth/login' ? () => true : (status) => status !== 401 && status !== 403

    const options = {
        url,
        method,
        validateStatus,
        ...other
    }
    options[method === 'GET' ? 'params' : 'data'] = params;

    console.log(options);

    try {
        const data = await api(options);
        return Promise.resolve(data);
    } catch (err) {
        console.log(err.response.status);
        if (err && err.response && err.response.status === 401) {
            return performTokenRefresh(options);
        } else {
            return Promise.reject(err);
        }
    }
};

const performTokenRefresh = async (options) => {
    const refresh_token = Cookies.get(REFRESH_TOKEN_COOKIE_NAME);
    if(!refresh_token) return {};
    const tokenRefreshResponse = await api.post('auth/createtoken', {
    }, {
        headers: {'Authorization': 'Bearer ' + refresh_token},
        validateStatus: () => true
    });
    if(tokenRefreshResponse.data.statusCode === 401 || tokenRefreshResponse.data.statusCode === 403) {
        Cookies.remove(REFRESH_TOKEN_COOKIE_NAME);
        if(!window.location.href.includes('login')) {
            window.location.href = "http://localhost:3000/login";
        }
        return {};
    }
    const access_token = tokenRefreshResponse.data.access_token;
    Cookies.set(TOKEN_COOKIE_NAME, access_token, { expires: 60 })
    api.defaults.headers.Authorization = `Bearer ${access_token}`
    return api(options);
}

export default api;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM