Next.js中Post/Put请求刷新Token时陷入无限循环求助
问题:Next.js应用Token过期后Post请求陷入无限循环
在基于Next.js开发的应用中,当Token过期后发起Post请求会陷入无限循环:Post请求返回401,触发Refresh-Token操作返回200,但重新发起Post请求仍返回401,循环往复。
以下是处理Refresh-Token的api.ts代码:
import { GetServerSidePropsContext } from "next" import axios, { AxiosError } from "axios" import { setCookie, parseCookies, destroyCookie } from "nookies" import { error as notifyError } from "helpers/notify/error" import { STORAGE } from "constants/storage" import { logOut } from "helpers/auth/logOut" import { ErrorResponse } from "shared/types" let isRefreshing = false let failedRequestsQueue: { onSuccess(token: string): void onFailure(err: AxiosError): void }[] = [] export function baseInstance( ctx: GetServerSidePropsContext | undefined = undefined ) { const cookies = parseCookies(ctx) const token = cookies[STORAGE.TOKEN_KEY] const api = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL }) api.defaults.headers.common.Authorization = `Bearer ${token}` api.interceptors.response.use( response => response, (error: AxiosError) => { const expectedError = error.response && error.response.status >= 400 && error.response.status < 500 if (!expectedError) { notifyError('Encontramos um problema por aqui.') } return Promise.reject(error) } ) return api } export function setupAPIClient( ctx: GetServerSidePropsContext | undefined = undefined ) { const cookies = parseCookies(ctx) const token = cookies[STORAGE.TOKEN_KEY] const api = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL }) api.defaults.headers.common.Authorization = `Bearer ${token}` axios.interceptors.request.use( config => { const cookies = parseCookies(ctx) const token = cookies[STORAGE.TOKEN_KEY] // eslint-disable-next-line no-param-reassign config.headers.authorization = `Bearer ${token}` api.defaults.headers.common.Authorization = `Bearer ${token}` return config }, error => { Promise.reject(error) } ) api.interceptors.response.use( response => response, (error: AxiosError<ErrorResponse>) => { const expectedError = error.response && error.response.status >= 400 && error.response.status < 500 if (!expectedError && error.response.status !== 401) { notifyError('Encontramos um problema por aqui.') } if (error.response.status === 401) { if (error.response.data.message === 'Refresh token not found') { logOut() } const cookies = parseCookies(ctx) const { '@mf_rt_key': refresh_token } = cookies const originalConfig = error.config if (!isRefreshing) { isRefreshing = true api .put('/refresh-tokens', { refresh_token }) .then(response => { const { token, refresh_token } = response.data setCookie(ctx, STORAGE.TOKEN_KEY, token, { maxAge: 30 * 24 * 60 * 60, // 30 days path: '/' }) setCookie(ctx, STORAGE.REFRESH_TOKEN_KEY, refresh_token, { maxAge: 30 * 24 * 60 * 60, // 30 days path: '/' }) api.defaults.headers.common.Authorization = `Bearer ${token}` failedRequestsQueue.forEach(request => request.onSuccess(token)) failedRequestsQueue = [] }) .catch((error: AxiosError) => { failedRequestsQueue.forEach(request => request.onFailure(error)) failedRequestsQueue = [] if (process.browser) { logOut() } }) .finally(() => { isRefreshing = false }) } return new Promise((resolve, reject) => { failedRequestsQueue.push({ onSuccess: (token: string) => { originalConfig.headers.Authorization = `Bearer ${token}` resolve(api(originalConfig)) }, onFailure: (error: AxiosError) => { reject(error) } }) }) } return Promise.reject(error) } ) return api }
我尝试了各种方法但均无效。

内容的提问来源于stack exchange,提问作者Júnior Silva
相关产品推荐
相关产品推荐

