Unix-мітки часу для JWT і строку дії токенів — як це працює

Якщо ви колись декодували JWT і бачили щось на кшталт "exp": 1744070400, ви вже зустрічали Unix-мітки часу в одному з найпрактичніших сценаріїв. Механіка строку дії JSON Web Token повністю побудована на Unix‑часі — і коли ви розумієте, як це працює, дебаг токен‑проблем стає значно простішим.

Unix Timestamp Converter миттєво перетворює будь‑яке “сире” число timestamp на читабельну дату. У цій статті — як JWT claims використовують Unix‑мітки, як рахувати час завершення дії токена і де зазвичай усе ламається.

Що насправді означають exp та iat

Розкодований payload JWT виглядає приблизно так:

{
  "sub": "user_12345",
  "iat": 1743984000,
  "exp": 1744070400,
  "role": "admin"
}

І iat (issued at), і exp (expiry) — це Unix‑мітки часу, тобто кількість секунд від 1 січня 1970 року 00:00:00 UTC. Це не має стосунку до локального часового поясу вашого сервера; це завжди UTC.

iat: 1743984000 означає, що токен видано в цю конкретну секунду. exp: 1744070400 означає, що токен стає недійсним у цю секунду. Різниця між ними — 86 400 секунд — і є дозволеним часом життя токена. У цьому прикладі — рівно 24 години.

Щоб побачити, якій даті відповідають ці значення, вставте будь‑яке число в Unix Timestamp Converter. 1743984000 відповідає April 7, 2026 00:00:00 UTC, а 1744070400 — April 8, 2026 00:00:00 UTC.

Як обчислюється “життя” токена

Логіка проста. Коли сервер випускає токен, він:

1. Берe поточний Unix‑timestamp (назвемо його now) 2. Додає бажану тривалість у секундах 3. Записує суму в claim exp

Для токена на 1 годину: exp = now + 3600 Для токена на 24 години: exp = now + 86400 Для токена на 7 днів: exp = now + 604800 Для токена на 30 днів: exp = now + 2592000

Коли клієнт надсилає токен, сервер перевіряє, чи поточний timestamp менший за exp. Якщо current_time > exp, токен відхиляють як протермінований.

Тут чиста ціла арифметика — без конвертацій часових поясів, без календарної логіки й без “пасток” довжини місяців. Це одна з причин, чому Unix‑мітки добре підходять для строків дії.

Типові строки дії токенів за сценаріями

Тип токенаТиповий строкСекунди
Короткоживучий access token15 хвилин900
Стандартний access token1 година3,600
API access token24 години86,400
Refresh token7 днів604,800
Довгоживучий refresh token30 днів2,592,000
Remember-me токен90 днів7,776,000
Посилання підтвердження email24–72 години86,400–259,200
Посилання скидання пароля15–60 хвилин900–3,600

Токени для скидання пароля та підтвердження email мають бути короткими — вони одноразові й чутливі. Refresh‑токени можуть бути довшими, бо зберігаються безпечніше і їх можна відкликати на сервері.

Як дебажити проблеми зі строком дії

Якщо токен раптово відхиляється, перший крок — декодувати його й подивитися на поле exp. Більшість JWT‑бібліотек мають функцію decode без перевірки підпису — це зручно для інспекції, коли потрібно лише прочитати claims.

Після того, як ви отримали exp, вставте значення в Unix Timestamp Converter, щоб побачити читабельний час завершення дії. Порівняйте його з поточним часом. Якщо токен закінчився три години тому — проблема у застарілому токені. Якщо строк у майбутньому, а токен все одно відхиляється — причина інша: невірний підпис, неправильний audience, або проблема clock skew.

Clock skew — поширена проблема в розподілених системах. Якщо сервер, що видає токен, і сервер, що його перевіряє, мають різницю годинника більш ніж кілька секунд, токени можуть відхилятися як “протерміновані”, хоча не повинні, або навпаки. Більшість JWT‑бібліотек дозволяє невелику толерантність до skew — зазвичай від 30 секунд до 5 хвилин.

Claim iat допомагає це помітити. Якщо iat “у майбутньому” з точки зору валідуючого сервера, то годинник сервера‑видавача випереджає. Якщо exp - iat не збігається з очікуваною тривалістю токена — під час видачі щось пішло не так.

Секунди vs мілісекунди: типова JWT-помилка

Unix‑мітки для JWT — у секундах. А Date.now() у JavaScript повертає мілісекунди. Ця невідповідність породжує баги, які легко не помітити.

Якщо ваш Node.js код робить так:

const exp = Date.now() + 3600; // Неправильно: Date.now() у мілісекундах

ви фактично ставите строк дії приблизно на 3,6 секунди в майбутньому (3600 мс), тобто майже “зараз”. Такий токен буде відхилений практично одразу.

Правильний варіант:

const exp = Math.floor(Date.now() / 1000) + 3600; // Правильно: спочатку в секунди

13‑значне число в exp — майже гарантований індикатор, що хтось випадково використав мілісекунди. Станом на 2026 рік стандартні Unix‑мітки в секундах мають 10 цифр. Якщо ви бачите exp: 1744070400000, це декодується як рік 57‑тисяч з чимось — явний сигнал, що мілісекунди “протекли” в поле, де очікуються секунди.

Claim nbf: Not Before

JWT також підтримує claim nbf (not before) — теж Unix‑timestamp. Він задає найраніший момент, коли токен стає дійсним. Якщо current_time < nbf, токен буде відхилений навіть якщо ще не прострочився.

Це корисно для токенів, які мають стати валідними в майбутньому — запланований доступ, тимчасове посилання на завантаження або токен, виданий наперед під подію. Комбінація nbf і exp визначає точне “вікно” валідності.

Приклад: `json { "nbf": 1744070400, "exp": 1744156800 } `

Цей токен стає дійсним April 8, 2026 00:00:00 UTC і завершує дію April 9, 2026 00:00:00 UTC — 24‑годинне вікно, що починається в майбутньому.

Відкликання токенів до завершення строку

Одне обмеження stateless‑JWT підходу: ви не можете “відкликати” токен до exp, не маючи стану на сервері. Якщо користувач вийшов із системи або токен скомпрометовано, він технічно лишається валідним до завершення — якщо не реалізувати блок‑лист.

Поширені підходи:

  • Короткоживучі access‑токени + refresh‑токени: тримайте access‑токени короткими (15 хв), відкликайте refresh‑токени на logout — access‑токен скоро сам завершиться.
  • Blocklist токенів: зберігайте відкликані ID токенів (зазвичай claim jti) на сервері до моменту exp. Більше накладних витрат, але дозволяє миттєве відкликання.
  • Ротація токенів: видавайте новий access‑токен при кожному refresh і робіть старий невалідним.

Unix‑timestamp у exp задає верхню межу валідності. А логіка вашого застосунку визначає, чи токен у цьому вікні справді має прийматися.

Як швидко прочитати строк дії на практиці

Якщо ви дебажите API й хочете швидко перевірити, чи токен не прострочений, не обов’язково підключати повну JWT‑бібліотеку. Розкодуйте payload (середній сегмент JWT) з base64, розпарсьте JSON і порівняйте exp з поточним Unix‑timestamp.

У консолі браузера: `javascript const payload = JSON.parse(atob(token.split('.')[1])); console.log('Expires:', new Date(payload.exp * 1000).toISOString()); console.log('Expired:', Date.now() / 1000 > payload.exp); `

Або просто вставте exp у Unix Timestamp Converter і отримайте дату без коду. Це зазвичай найшвидший спосіб відповісти на питання “цей токен уже протермінований?” під час дебагу в продакшені.

Схожі статті