fix: Improve token refresh logic and API interceptor handling (#7158)

* 🐛 (api.tsx): fix logic to correctly handle refreshing access token and retrying requests on authentication errors
🐛 (use-post-refresh-access.ts): fix retry logic to always retry refreshing access token regardless of auto login setting

*  (use-get-autologin.ts): add support for autoLogin state in useGetAutoLogin hook to handle auto login scenarios more effectively
📝 (use-post-refresh-access.ts): import and use autoLogin state from authStore in useRefreshAccessToken hook to determine retry count based on auto login status
This commit is contained in:
Cristhian Zanforlin Lousa 2025-03-19 10:20:55 -03:00 committed by GitHub
commit 828e9eab78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 20 deletions

View file

@ -65,25 +65,27 @@ function ApiInterceptor() {
const isAuthenticationError =
error?.response?.status === 403 || error?.response?.status === 401;
if (isAuthenticationError && !IS_AUTO_LOGIN) {
if (autoLogin !== undefined && !autoLogin) {
if (
error?.config?.url?.includes("github") ||
error?.config?.url?.includes("public")
) {
return Promise.reject(error);
}
const stillRefresh = checkErrorCount();
if (!stillRefresh) {
return Promise.reject(error);
}
const shouldRetryRefresh =
(isAuthenticationError && !IS_AUTO_LOGIN) ||
(isAuthenticationError && !autoLogin && autoLogin !== undefined);
await tryToRenewAccessToken(error);
if (shouldRetryRefresh) {
if (
error?.config?.url?.includes("github") ||
error?.config?.url?.includes("public")
) {
return Promise.reject(error);
}
const stillRefresh = checkErrorCount();
if (!stillRefresh) {
return Promise.reject(error);
}
const accessToken = cookies.get(LANGFLOW_ACCESS_TOKEN);
if (!accessToken && error?.config?.url?.includes("login")) {
return Promise.reject(error);
}
await tryToRenewAccessToken(error);
const accessToken = cookies.get(LANGFLOW_ACCESS_TOKEN);
if (!accessToken && error?.config?.url?.includes("login")) {
return Promise.reject(error);
}
}

View file

@ -31,6 +31,7 @@ export const useGetAutoLogin: useQueryFunctionType<undefined, undefined> = (
const isLoginPage = location.pathname.includes("login");
const navigate = useCustomNavigate();
const { mutateAsync: mutationLogout } = useLogout();
const autoLogin = useAuthStore((state) => state.autoLogin);
const retryCountRef = useRef(0);
const retryTimerRef = useRef<NodeJS.Timeout | null>(null);
@ -67,8 +68,13 @@ export const useGetAutoLogin: useQueryFunctionType<undefined, undefined> = (
};
const handleAutoLoginError = async () => {
const manualLoginNotAuthenticated = !isAuthenticated && !IS_AUTO_LOGIN;
const autoLoginNotAuthenticated = !isAuthenticated && IS_AUTO_LOGIN;
const manualLoginNotAuthenticated =
(!isAuthenticated && !IS_AUTO_LOGIN) ||
(!isAuthenticated && autoLogin !== undefined && !autoLogin);
const autoLoginNotAuthenticated =
(!isAuthenticated && IS_AUTO_LOGIN) ||
(!isAuthenticated && autoLogin !== undefined && autoLogin);
if (manualLoginNotAuthenticated) {
await mutationLogout();

View file

@ -1,4 +1,5 @@
import { IS_AUTO_LOGIN, LANGFLOW_REFRESH_TOKEN } from "@/constants/constants";
import useAuthStore from "@/stores/authStore";
import { useMutationFunctionType } from "@/types/api";
import { Cookies } from "react-cookie";
import { api } from "../../api";
@ -17,6 +18,7 @@ export const useRefreshAccessToken: useMutationFunctionType<
> = (options?) => {
const { mutate } = UseRequestProcessor();
const cookies = new Cookies();
const autoLogin = useAuthStore((state) => state.autoLogin);
async function refreshAccess(): Promise<IRefreshAccessToken> {
const res = await api.post<IRefreshAccessToken>(`${getURL("REFRESH")}`);
@ -27,7 +29,7 @@ export const useRefreshAccessToken: useMutationFunctionType<
const mutation = mutate(["useRefreshAccessToken"], refreshAccess, {
...options,
retry: IS_AUTO_LOGIN ? 0 : 3,
retry: IS_AUTO_LOGIN || autoLogin ? 0 : 2,
});
return mutation;