Безопасные шаблоны аутентификации
Хранение токена (в памяти, в localStorage или в cookie httpOnly), тихое обновление и выход при закрытии вкладки
«Безопасные шаблоны аутентификации» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Предотвращение XSS во Vue
- Политика безопасности содержимого (CSP) с Vue
- Защита от CSRF в SPA на Vue
- Безопасные шаблоны аутентификации