В спецификации JWT (JSON Web Token) срок жизни токена контролируется
через стандартное поле exp (expiration time). Оно хранит
метку времени в формате Unix timestamp и определяет момент, после
которого токен считается недействительным.
В библиотеке Jose проверка этого поля выполняется автоматически при
верификации подписи JWT, если используется функция проверки,
ориентированная на JWS, например jwtVerify.
Основная логика обработки истечения срока действия строится вокруг двух аспектов:
expПри вызове:
import { jwtVerify } from 'jose'
const { payload } = await jwtVerify(token, secret)
библиотека выполняет несколько шагов:
expЕсли текущий timestamp превышает значение exp,
выполнение прерывается и выбрасывается исключение.
Важный момент: проверка времени выполняется автоматически и не требует ручной реализации.
При истечении срока действия токена Jose генерирует специализированную ошибку:
JWTExpiredОна наследуется от базового класса ошибок JWT и содержит дополнительную информацию о причине сбоя.
Пример обработки:
import { jwtVerify, errors } from 'jose'
try {
const { payload } = await jwtVerify(token, secret)
} catch (err) {
if (err instanceof errors.JWTExpired) {
// токен просрочен
}
}
Объект ошибки может содержать:
payload — декодированные данные токена (если
доступны)message — текстовое описание причиныcode — тип ошибкиРеальные системы часто сталкиваются с проблемой рассинхронизации времени между клиентом и сервером. Даже небольшая разница в несколько секунд может приводить к ложному срабатыванию истечения токена.
Для решения этой проблемы в Jose предусмотрен параметр
clockTolerance.
await jwtVerify(token, secret, {
clockTolerance: '10s'
})
Значение задаёт допустимое отклонение времени в обе стороны. Это означает:
exp
находится в пределах допускаПри создании токена важно корректно задавать время жизни:
import { SignJWT } from 'jose'
const token = await new SignJWT({ userId: 123 })
.setProtectedHeader({ alg: 'HS256' })
.setExpirationTime('2h')
.sign(secret)
Поддерживаются форматы:
"2h", "30m",
"1d")Некорректно заданный exp приводит к немедленной
инвалидности токена или ошибке при валидации.
В прикладных системах истечение токена не рассматривается как исключительная ситуация, а является частью нормального жизненного цикла авторизации.
Типовой поток обработки:
JWTExpiredВажно, что логика обновления токена не должна выполняться внутри Jose — библиотека отвечает только за криптографическую проверку и валидацию структуры.
Истечение срока действия чаще всего применяется только к access token.
Refresh token:
Такое разделение снижает риск компрометации системы, ограничивая время жизни активного доступа.
Поле exp не решает задачу принудительной отзыва токена
до его истечения. Для этого применяются дополнительные механизмы:
jti)Jose при этом остаётся на уровне проверки подписи и времени, не управляя состоянием токена.
В некоторых сценариях требуется только декодирование payload без проверки подписи:
import { decodeJwt } from 'jose'
const payload = decodeJwt(token)
В этом случае:
exp доступноТакой подход используется редко и только для некритичных операций (например, отображение информации до полной проверки).
Корректная обработка истёкших токенов обычно включает несколько уровней защиты:
jwtVerifyclockTolerance для устранения расхождений
времениJWTExpiredТакая комбинация позволяет избежать как ложных отказов доступа, так и использования устаревших токенов в распределённых системах