JavaRush /Курсы /Модуль 3: React /Обработка автоматического выхода при истечении времени се...

Обработка автоматического выхода при истечении времени сессии

Модуль 3: React
16 уровень , 7 лекция
Открыта

Почему устаревание токенов — это важно?

Представьте, что кто-то украл ваш JWT. Если он будет действителен бесконечно, то воришка сможет вечно пользоваться привилегиями вашей учётной записи. Поэтому токены всегда имеют время жизни (TTL) — например, 15 минут или час. После этого токен становится недействительным, и пользователь теряет доступ, если не обновит его.

Работа с истекающими токенами требует:

  1. Обеспечения безопасного автоматического выхода пользователя.
  2. Обновления токена через механизм Refresh Tokens, если это поддерживается.

Как обработать истечение времени сессии?

Шаг 1: настройка времени жизни токенов

Когда сервер выдаёт JWT, он добавляет в его "нагрузочную часть" payload информацию о времени, до которого токен действителен. Вот пример JWT с временем жизни:

{
  "sub": "user123",
  "role": "user",
  "exp": 1696108800
}

Здесь exp (expiration) — это UNIX-временная метка, указывающая, что токен истекает в определённое время.

Чтобы настроить срок действия токенов, убедитесь, что ваш сервер правильно добавляет время истечения:

const jwt = require('jsonwebtoken');

// Генерация токена с временем жизни 15 минут
const token = jwt.sign(
  { sub: "user123", role: "user" },
  process.env.JWT_SECRET,
  { expiresIn: '15m' }
);

Теперь токен станет недействительным через 15 минут после его генерации.

Шаг 2: проверка времени истечения токена в клиентском приложении

Для того, чтобы автоматически выйти пользователя, когда токен больше недействителен, нам нужно уметь проверять его "срок годности". Это можно сделать прямо на клиенте, декодировав токен.

Для этого воспользуемся библиотекой jwt-decode:

npm install jwt-decode

Пример кода для проверки истечения токена:

import jwtDecode from 'jwt-decode';

interface DecodedToken {
  exp: number; // Время истечения токена в формате UNIX
}

// Функция для проверки, истёк ли токен
const isTokenExpired = (token: string): boolean => {
  try {
    const decoded: DecodedToken = jwtDecode(token);
    const currentTime = Math.floor(Date.now() / 1000); // Текущее время в формате UNIX
    return decoded.exp < currentTime; // Если exp меньше текущего времени, токен истёк
  } catch (err) {
    console.error("Ошибка при декодировании токена", err);
    return true; // Если токен невалидный, считаем, что он истёк
  }
};

Используйте эту функцию, чтобы проверить токен перед выполнением любой защищённой операции.

Шаг 3: автоматический выход пользователя

Если токен истёк, лучше сразу вывести пользователя из приложения и перенаправить его на страницу входа. Вот как это можно сделать:

  1. Создаём хук для отслеживания истечения токена:
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";

const useSessionTimeout = (token: string | null) => {
  const navigate = useNavigate();

  useEffect(() => {
    if (!token) return;

    const decoded: DecodedToken = jwtDecode(token);
    const tokenExpirationTime = decoded.exp * 1000; // Переводим в миллисекунды
    const currentTime = Date.now();

    const timeoutId = setTimeout(() => {
      // Очищаем данные и перенаправляем на страницу входа
      localStorage.removeItem("token");
      navigate("/login"); // Например, перенаправляем на страницу входа
    }, tokenExpirationTime - currentTime);

    // Очищаем таймаут при размонтировании компонента
    return () => clearTimeout(timeoutId);
  }, [token, navigate]);
};
  1. Используем этот хук в вашем App-компоненте:
export const App = () => {
  const token = localStorage.getItem("token");

  useSessionTimeout(token);

  return (
    <Routes>
      <Route path="/login" element={<Login />} />
      <Route path="/dashboard" element={<ProtectedRoute component={Dashboard} />} />
    </Routes>
  );
};

Теперь, если токен истёк, происходит автоматический выход, и пользователь перенаправляется на страницу входа.

Шаг 4: обновление токена с использованием Refresh Token

Истечение токена можно обрабатывать и более "гладко", не разлогинивая пользователя. Для этого используется Refresh Token, который имеет гораздо более длительный срок жизни (например, неделю или месяц).

Пример работы с Refresh Token на клиенте:

const refreshToken = async () => {
  try {
    const response = await fetch("/api/refresh-token", {
      method: "POST",
      credentials: "include", // Для отправки куки
    });

    if (response.ok) {
      const data = await response.json();
      localStorage.setItem("token", data.token); // Сохраняем новый токен
    } else {
      throw new Error("Не удалось обновить токен");
    }
  } catch (error) {
    console.error("Ошибка при обновлении токена", error);
    localStorage.removeItem("token");
    navigate("/login");
  }
};

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

Особенности работы с сервером

Для автоматического выхода или обновления токена сервер тоже должен быть настроен соответствующим образом:

  1. Срок жизни токенов: убедитесь, что access_token имеет короткий срок действия, а refresh_token — длительный.
  2. Обработка истечения: если access_token больше недействителен, но у клиента есть валидный refresh_token, сгенерируйте новый access_token и отправьте его пользователю.
  3. Безопасное хранение refresh_token: лучше всего хранить refresh_token в HTTP-only cookies, чтобы он был защищён от XSS-атак.

Типичные ошибки и проблемы

  1. Игнорирование времени истечения токена на клиенте. Не забывайте проверять токен перед каждым API-запросом.
  2. Слишком длинный срок действия токенов. Долгоживущий токен — это подарок для хакеров.
  3. Неправильная работа с таймерами. Например, если пользователь обновляет токен, важно обновлять и таймер.

Теперь, когда вы знаете, как работать с истекающими токенами, вы готовы сделать ваше приложение ещё более безопасным и профессиональным!

2
Задача
Модуль 3: React, 16 уровень, 7 лекция
Недоступна
Автоматический выход при истечении токена
Автоматический выход при истечении токена
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ