Аутентификация JWT: вход и обновление
Поток access token и refresh token, cookie httpOnly и тихое обновление с перехватчиками
«Аутентификация JWT: вход и обновление» — бесплатный урок Vue Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.
Модель token доступа и token обновления
Надёжная схема JWT использует два token: короткоживущий token доступа (несколько минут), отправляемый с каждым запросом к API, и долгоживущий token обновления (несколько дней), используемый только для выпуска новых token доступа. Это ограничивает последствия утечки token доступа.
Регистрация плагина JWT
С Fastify зарегистрируйте @fastify/jwt и укажите надёжный секрет. Это добавит вспомогательные средства для подписи и проверки в объект приложения и объект запроса.
import jwt from '@fastify/jwt'
await app.register(jwt, {
secret: process.env.JWT_SECRET
})Маршрут входа
POST /auth/login проверяет учётные данные, затем выдаёт оба token. Никогда не храните пароли в открытом виде — сравнивайте их с хешем (bcrypt/argon2).
app.post('/auth/login', async (req, reply) => {
const { email, password } = req.body
const user = await findUser(email)
if (!user || !(await verifyHash(password, user.hash))) {
return reply.code(401).send({ error: 'Invalid credentials' })
}
// ... sign tokens (next scene)
})Подписание token доступа
Подпишите короткоживущий token доступа, указав идентификатор пользователя и минимальный набор утверждений. Срок действия должен быть коротким (например, 15 минут).
const accessToken = app.jwt.sign(
{ sub: user.id, role: user.role },
{ expiresIn: '15m' }
)Подписание token обновления
Подпишите долгоживущий token обновления с отличительным маркером в payload (или отдельным секретом). Он используется только в маршруте обновления.
const refreshToken = app.jwt.sign(
{ sub: user.id, type: 'refresh' },
{ expiresIn: '7d' }
)Token обновления в cookie httpOnly
Сохраните token обновления в защищённом cookie с атрибутами httpOnly и SameSite. JavaScript не может его прочитать (что снижает риск кражи через XSS), а браузер автоматически отправляет его на маршрут обновления.
reply.setCookie('refreshToken', refreshToken, {
httpOnly: true,
sameSite: 'strict',
secure: true, // HTTPS only
path: '/auth/refresh',
maxAge: 60 * 60 * 24 * 7
})Возврат token доступа в теле ответа
Token доступа возвращается в теле JSON-ответа. Приложение Vue хранит его в памяти (не в localStorage) и добавляет к запросам API. Token обновления никогда не появляется в теле.
return reply.send({
accessToken,
user: { id: user.id, name: user.name }
})
// refreshToken is only in the httpOnly cookieПочему не следует хранить token доступа в localStorage
localStorage доступен для чтения любому скрипту, поэтому ошибка XSS может украсть находящийся там token. Хранение token доступа в памяти JS, а token обновления — в cookie с флагом httpOnly уменьшает масштаб последствий XSS.
Маршрут обновления
POST /auth/refresh читает token обновления из cookie, проверяет его и выпускает новый token доступа. Свежий token доступа возвращается в теле ответа.
app.post('/auth/refresh', async (req, reply) => {
const token = req.cookies.refreshToken
if (!token) return reply.code(401).send()
try {
const payload = app.jwt.verify(token)
const accessToken = app.jwt.sign(
{ sub: payload.sub }, { expiresIn: '15m' }
)
return reply.send({ accessToken })
} catch {
return reply.code(401).send({ error: 'Invalid refresh' })
}
})Защита маршрутов
Добавьте preHandler, который проверяет token доступа из заголовка Authorization. @fastify/jwt с помощью request.jwtVerify() вызывает исключение при недействительных или просроченных token и возвращает 401.
app.get('/api/me', {
preHandler: async (req, reply) => {
try { await req.jwtVerify() }
catch { reply.code(401).send({ error: 'Unauthorized' }) }
}
}, async (req) => getProfile(req.user.sub))Выход: очистка cookie
Выход очищает cookie обновления, поэтому его больше нельзя использовать для выпуска token доступа. Для более надёжной защиты также отслеживайте и отзывайте token обновления на сервере (с помощью списка запрещённых token или ротации).
app.post('/auth/logout', async (req, reply) => {
reply.clearCookie('refreshToken', { path: '/auth/refresh' })
return reply.send({ ok: true })
})Быстрая проверка
Проверьте, насколько хорошо Вы поняли аутентификацию JWT.
Итоги
Вы научились выполнять вход и обновление с помощью JWT:
- Короткоживущий token доступа и долгоживущий token обновления
POST /auth/loginпроверяет учётные данные и подписывает оба token- Token обновления помещается в защищённый cookie httpOnly SameSite Secure
- Token доступа возвращается в теле ответа и хранится в памяти JS
POST /auth/refreshвыпускает новый token доступа из cookie
Часто задаваемые вопросы
Урок «Аутентификация JWT: вход и обновление» бесплатный?
Да — полный текст урока «Аутентификация JWT: вход и обновление» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.
Чему я научусь в уроке «Аутентификация JWT: вход и обновление»?
Поток access token и refresh token, cookie httpOnly и тихое обновление с перехватчиками Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Vue Academy?
Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Аутентификация JWT: вход и обновление»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Vue Academy?
Да. Каждый урок Vue Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Бэкенд Fastify для SPA на Vue
- Аутентификация JWT: вход и обновление
- Аутентифицированные вызовы API с перехватчиками Axios
- Развёртывание полнофункционального Vue-приложения в продакшене