Vue Academy · Урок

Безопасные шаблоны аутентификации

Хранение токена (в памяти, в localStorage или в cookie httpOnly), тихое обновление и выход при закрытии вкладки

Урок 4 из 413 шагов

«Безопасные шаблоны аутентификации» — бесплатный урок Vue Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.

Токены и место их хранения

SPA используют токены для аутентификации, но место их хранения определяет степень уязвимости к XSS и CSRF. Современный подход разделяет недолговечный токен доступа и долгоживущий токен обновления, сохраняя их по-разному.

Проблема localStorage

Хранить токены в localStorage удобно, но опасно: любой скрипт, внедренный при атаке XSS, может прочитать токен и передать его злоумышленнику. Не храните там учетные данные.

// AVOID
localStorage.setItem("token", accessToken);

Токен доступа в памяти

Храните токен доступа в переменной JavaScript или реактивной ссылке ref. При перезагрузке он исчезает, поэтому даже успешная атака XSS имеет гораздо меньше возможностей для нанесения вреда, а на диске ничего не сохраняется.

import { ref } from "vue";

export const accessToken = ref(null);

Токен обновления в cookie httpOnly

Токен обновления хранится в куке с атрибутами HttpOnly, Secure и SameSite. JavaScript не может прочитать его, поэтому XSS не сможет его украсть, а браузер отправляет его только на конечную точку авторизации.

Set-Cookie: refresh=...; HttpOnly; Secure; SameSite=Strict; Path=/auth

Добавление токена доступа

Перехватчик запросов Axios добавляет хранящийся в памяти токен доступа в заголовок Authorization при каждом вызове.

api.interceptors.request.use((config) => {
  if (accessToken.value) {
    config.headers.Authorization = "Bearer " + accessToken.value;
  }
  return config;
});

Определение истечения срока: 401

Когда срок действия токена доступа истекает, сервер отвечает кодом 401 Unauthorized. Перехватчик ответов перехватывает этот ответ и запускает обновление токена.

api.interceptors.response.use(
  (res) => res,
  async (error) => {
    if (error.response?.status === 401) {
      // attempt refresh
    }
    return Promise.reject(error);
  }
);

Обновление токена

При ответе 401 вызовите конечную точку обновления. Браузер автоматически отправит куку обновления httpOnly (withCredentials), а сервер вернет новый токен доступа.

const { data } = await axios.post("/auth/refresh", null, {
  withCredentials: true
});
accessToken.value = data.accessToken;

Повтор исходного запроса

После refreshing повторите исходный неудачный запрос с новым токеном, чтобы пользователь ничего не заметил.

async (error) => {
  const original = error.config;
  if (error.response?.status === 401 && !original._retry) {
    original._retry = true;
    const { data } = await axios.post("/auth/refresh", null, { withCredentials: true });
    accessToken.value = data.accessToken;
    original.headers.Authorization = "Bearer " + data.accessToken;
    return api(original);
  }
  return Promise.reject(error);
}

Предотвращение лавины обновлений

Если сразу несколько запросов получают ответ 401, поставьте их в очередь за одним выполняющимся обновлением, чтобы не отправлять запрос к конечной точке обновления повторно.

let refreshing = null;
function refresh() {
  if (!refreshing) {
    refreshing = axios.post("/auth/refresh", null, { withCredentials: true })
      .finally(() => { refreshing = null; });
  }
  return refreshing;
}

Выход из системы

При выходе из системы удалите токен из памяти и вызовите конечную точку, которая очистит cookie обновления на стороне сервера.

async function logout() {
  accessToken.value = null;
  await axios.post("/auth/logout", null, { withCredentials: true });
}

Сочетание с защитой CSRF

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

Быстрая проверка

Где следует хранить токен доступа и токен обновления?

Итоги

Храните токен доступа в ref в памяти (никогда не используйте для этого localStorage), а токен обновления — в cookie HttpOnly. Перехватчик запросов добавляет токен bearer; перехватчик ответов перехватывает 401, вызывает конечную точку обновления, обновляет токен и повторяет original-запрос, устраняя дублирование одновременных обновлений и дополняя защиту механизмами CSRF.

Можно начать бесплатно

Изучай HTML с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
42
Уроки
156

Часто задаваемые вопросы

Урок «Безопасные шаблоны аутентификации» бесплатный?

Да — полный текст урока «Безопасные шаблоны аутентификации» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.

Чему я научусь в уроке «Безопасные шаблоны аутентификации»?

Хранение токена (в памяти, в localStorage или в cookie httpOnly), тихое обновление и выход при закрытии вкладки Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Vue Academy?

Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Безопасные шаблоны аутентификации»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Vue Academy?

Да. Каждый урок Vue Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Предотвращение XSS во Vue
  2. Политика безопасности содержимого (CSP) с Vue
  3. Защита от CSRF в SPA на Vue
  4. Безопасные шаблоны аутентификации
← Назад к Vue Academy