From d983e1dce74415dd06ab40453dcdec55115df3b1 Mon Sep 17 00:00:00 2001 From: Primakov Alexandr Date: Thu, 18 Dec 2025 12:11:31 +0300 Subject: [PATCH] Enhance authentication flow by adding token refresh mechanism and improving error handling. Implement checks to prevent authentication loops during API calls and ensure token is updated before requests. This improves user experience and security in the application. --- src/__data__/api/api.ts | 26 +++++++++++++++++++++++--- src/index.tsx | 15 ++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/__data__/api/api.ts b/src/__data__/api/api.ts index 10a5ee3..6dee244 100644 --- a/src/__data__/api/api.ts +++ b/src/__data__/api/api.ts @@ -31,15 +31,35 @@ export const api = createApi({ ) => { const response = await fetch(input, init) - if (response.status === 403) keycloak.login() + if (response.status === 401 || response.status === 403) { + const { isAuthLoopBlocked, recordAuthAttempt } = await import('../../utils/authLoopGuard') + + if (!isAuthLoopBlocked()) { + recordAuthAttempt() + keycloak.login() + } else { + console.error('Auth loop detected, not redirecting to login') + } + } return response }, headers: { 'Content-Type': 'application/json;charset=utf-8', }, - prepareHeaders: (headers) => { - headers.set('Authorization', `Bearer ${keycloak.token}`) + prepareHeaders: async (headers) => { + try { + // Обновить токен, если он истекает в течение 30 секунд + await keycloak.updateToken(30) + } catch (error) { + console.error('Failed to refresh token:', error) + } + + if (keycloak.token) { + headers.set('Authorization', `Bearer ${keycloak.token}`) + } + + return headers }, }), tagTypes: ['Task', 'Chain', 'User', 'Submission', 'Stats'], diff --git a/src/index.tsx b/src/index.tsx index 81efdfd..3c08658 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -34,9 +34,22 @@ export const mount = async (Component, element = document.getElementById('app')) recordAuthAttempt() await keycloak.init({ - onLoad: 'login-required' + onLoad: 'login-required', + checkLoginIframe: false }) + // Настройка автоматического обновления токена + setInterval(() => { + keycloak.updateToken(70).then((refreshed) => { + if (refreshed) { + console.log('Token was successfully refreshed') + } + }).catch(() => { + console.error('Failed to refresh token, redirecting to login') + keycloak.login() + }) + }, 60000) // Проверять каждую минуту + const userInfo = await keycloak.loadUserInfo() if (userInfo && keycloak.tokenParsed) {