Как правильно обновлять access-токен на фронтенде?

Меня давно интересует, как работает процесс обновления токенов в системе аутентификации. У меня есть следующая ситуация: я использую стандартную схему с refresh и access токенами, а также эндпоинт auth/refresh. Когда я отправляю refresh-токен на этот эндпоинт, я получаю новые refresh и access токены. 

Как фронтенд определяет, когда срок действия access-токена истекает и когда следует отправить запрос на эндпоинт обновления? Что происходит, если пользователь закроет страницу? Не возникает ли при следующем входе ситуация, когда его сессия просто сбрасывается? Как разработчики обычно решают подобные проблемы?
  • 25 марта 2025 г. 7:24
Ответы на вопрос 2
Обновление access-токена на фронтенде — это важный аспект работы с аутентификацией, особенно когда используетя схема с refresh-токенами. Вот несколько рекомендаций и подходов, которые помогут правильно организовать этот процесс:

### 1. Хранение информации о токенах

Обычно токены (как access, так и refresh) хранятся в безопасном месте, например:
- В `localStorage` или `sessionStorage`
- В cookies (желательно с флагом `HttpOnly` и `Secure`)

### 2. Установка и управление временем жизни токенов

Access-токены обычно имеют короткий срок действия (например, 15 минут), в то время как refresh-токены — более длительный (например, несколько дней или недель). При получении access-токена от сервера имеет смысл сохранить информацию о времени его истечения.

### 3. Определение момента, когда нужно обновить токен

На фронтенде можно использовать `setTimeout` или проверять каждый раз перед отправкой запроса, если access-токен близок к истечению:

- **Polling**: Установка таймера, который будет вызывать обновление токена за несколько минут до его истечения.
- **Запрос перед использованием**: Проверка времени жизни токена каждый раз перед отправкой защищенного запроса. Если токен истекает, отправляем запрос на обновление.

### 4. Логика обновления токенов

Когда время доступа токена близко к истечению или когда происходит ошибка аутентификации (например, 401 Unauthorized), нужно:

1. Отправить запрос на refresh-токен.
2. Если обновление прошло успешно, сохранить новые токены и перезапустить изначальный запрос.
3. Обработать ситуации, когда refresh-токен также истек или недействителен (например, вывести пользователя на страницу входа).

### 5. Обработка закрытия страницы

Если пользователь закроет страницу и вернется позже, можно использовать сохраненные токены из `localStorage`, чтобы обеспечить более плавный процесс входа.

1. Если access-токен истек и refresh-токен по-прежнему действителен, можно автоматически обновить access-токен при загрузке приложения.
2. Если оба токена недействительны, следует перенаправить пользователя на страницу входа.

### 6. Примеры реализации

Вот пример кода, как можно организовать обновление токена:

```javascript
const TOKEN_EXPIRATION_TIME = 15 * 60 * 1000; // 15 минут
const REFRESH_THRESHOLD = 5 * 60 * 1000; // 5 минут до истечения

function isTokenExpired(expirationTime) {
    return Date.now() > expirationTime;
}

async function refreshTokenIfNeeded() {
    const accessTokenExpiration = getAccessTokenExpiration(); // вернуть время истечения
    if (isTokenExpired(accessTokenExpiration - REFRESH_THRESHOLD)) {
        const response = await fetch('/auth/refresh', {
            method: 'POST',
            credentials: 'include', // если используете cookies
        });

        if (response.ok) {
            const { accessToken, refreshToken } = await response.json();
            saveTokens(accessToken, refreshToken); // сохраняем в storage
        } else {
            redirectToLogin();
        }
    }
}

// Вызывать refreshTokenIfNeeded перед защитой запросами
async function protectedAPIRequest() {
    await refreshTokenIfNeeded();
    // Выполнение защищенного API-запроса
}
```

### Заключение

Использование refresh-токенов позволяет обходиться без частого запроса пароля пользователя. Но важно реализовать всю систему с учетом обработки ошибок, безопасности и удобства для пользователей. Важно также следить за сроками действия токенов и обрабатывать ситуации, когда пользователь неактивен или необходимо упрощенное повторное аутентификацию.
1. запрос с протухшим обычно даст 401, ты запускаешь процесс получения нового токена и повторяешь запрос 
2. обычно с токеном передает время жизни, можно самому контролировать его и не допускать пункт 2

А что если пользователь закроет страницу, получается при следующем входе его "вход" просто сброшен
это почему? повторюсь, процесс получения нового токена для юзера прозрачный.

Да, самое главное, перестаньте использовать jwt в юзерском фронтент-бекенд, он лучше всего подходит для взаимодействия между сервисами
Похожие вопросы