【问题标题】:Issue with axios-auth-refreshaxios-auth-refresh 的问题
【发布时间】:2021-03-04 23:08:27
【问题描述】:

我正在尝试从反应中实现刷新令牌。我正在使用这个库 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;

如果返回 401,以下 api 调用不会重复:

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

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

如果返回 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();
    }, [])

请帮忙。

【问题讨论】:

    标签: javascript node.js reactjs refresh-token


    【解决方案1】:

    在这个问题上花了一些时间后,我决定创建一个通用 API 调用程序,而不是使用 axios 拦截器或任何其他库。这是我的通用 axios API 调用者。它仍然可以改进,但想法是如果第一个令牌已过期,则使用新令牌再次调用 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;
    

    【讨论】:

      猜你喜欢
      • 2021-06-12
      • 1970-01-01
      • 2020-02-12
      • 2020-04-25
      • 1970-01-01
      • 2016-12-09
      • 2020-02-03
      • 2011-07-12
      • 2020-12-21
      相关资源
      最近更新 更多