Flyrell / axios-auth-refresh

Library that helps you implement automatic refresh of authorization via axios interceptors. You can easily intercept the original request when it fails, refresh the authorization and continue with the original request, without user even noticing.
MIT License
1.06k stars 91 forks source link

Cannot call request api 401 again after get new acccessToken when using react-query #283

Open ducyb782001 opened 6 months ago

ducyb782001 commented 6 months ago

Hi every one, i have api.ts file like that

const client = axios.create({
  url: process.env.NEXT_PUBLIC_BASE_URL,
  headers: {
    "x-api-key": process.env.NEXT_PUBLIC_DGG_API_KEY,
  },
})

export const refreshAccessToken = async () => {
  const cookies = cookie.parse(window?.document.cookie)

  const onSuccess = (response) => {
    const data = response?.data
    processDataLogin(data)
  }

  const onError = (error) => {
    localStorage.clear()
    window.document.cookie = cookie.serialize("accessToken", "", {
      maxAge: -1, // Expire the accessToken immediately.
      path: "/",
    })
    window.document.cookie = cookie.serialize("refreshToken", "", {
      maxAge: -1, // Expire the refreshToken immediately.
      path: "/",
    })
    browserRedirectToIndexAfterSignOut()
    return error
  }

  const payload = {
    refreshToken: cookies.refreshToken,
  }

  if (cookies.refreshToken && !cookies.accessToken) {
    try {
      const response = await client({
        method: "post",
        url: refreshAccessTokenUrl,
        data: payload,
      })
      onSuccess(response)
    } catch (error) {
      onError(error)
    }
  }
}

export const requestAPI = async ({ ...options }) => {
  console.log("Call to request api", options)
  const cookies = cookie.parse(window?.document.cookie)
  const acceptLanguage = localStorage.getItem("i18nextLng")
  if (cookies.accessToken) {
    console.log("Go line 96: ", cookies)
    client.defaults.headers.common.Authorization = `Bearer ${cookies?.accessToken || ""}`
  }

  if (acceptLanguage) {
    client.defaults.headers.common["Accept-Language"] = acceptLanguage
  }

  const onSuccess = (response) => response
  const onError = async (error) => {
    return error
  }
  return client(options).then(onSuccess).catch(onError)
}

createAuthRefreshInterceptor(client, refreshAccessToken)

I add some log and i realize after one request get 401 error. It will call refresh api immediately => get new accessToken and then call api again. But new api don't have accessToken. It quite strang, any one can help me? image

My version is:

"axios": "^0.27.2",
"axios-auth-refresh": "^3.3.6",
sahand-sn commented 2 months ago

i have similar problem

ducyb782001 commented 2 months ago

i have similar problem

Do you resolved this problem? I move the header of client interceptors to global of this file and it will resolved

client.interceptors.request.use(
  (request) => {
    const cookies = cookie.parse(window?.document.cookie)
    const acceptLanguage = localStorage.getItem("i18nextLng")
    if (cookies.accessToken) {
      request.headers["Authorization"] = `Bearer ${cookies.accessToken}`
    }
    if (acceptLanguage) {
      request.headers["Accept-Language"] = acceptLanguage
    }
    return request
  },
  (error) => {
    return Promise.reject(error)
  },
)

You can try it

sahand-sn commented 1 month ago

i have similar problem

Do you resolved this problem? I move the header of client interceptors to global of this file and it will resolved

client.interceptors.request.use(
  (request) => {
    const cookies = cookie.parse(window?.document.cookie)
    const acceptLanguage = localStorage.getItem("i18nextLng")
    if (cookies.accessToken) {
      request.headers["Authorization"] = `Bearer ${cookies.accessToken}`
    }
    if (acceptLanguage) {
      request.headers["Accept-Language"] = acceptLanguage
    }
    return request
  },
  (error) => {
    return Promise.reject(error)
  },
)

You can try it

i added a flag to stop looping