Безпека · 3 хв читання ·
Що всередині JWT і чому декодувати — не означає перевірити
JSON Web Token схожий на набір випадкових символів, але прочитати його може будь-хто. Що зберігається в трьох його частинах і яка помилка призводить до дірок у безпеці.

JWT (JSON Web Token) — той довгий рядок, завдяки якому ви залишаєтеся авторизованими в багатьох вебзастосунках і API. Він виглядає зашифрованим, але найчастіше це не так: будь-хто, у кого є токен, може прочитати його вміст.
Три частини через крапку
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.3q2-7w…
└ header ──────────┘ └ payload ───────┘ └ signature
Header повідомляє, як підписано токен, наприклад HS256 або RS256. Payload містить claims: хто користувач (sub), коли видано токен (iat) і коли він спливає (exp), а також усе, що додає застосунок, наприклад ролі. Обидві частини — звичайний JSON у кодуванні base64url, а це кодування, а не шифрування.
Головне — підпис
Третя частина — підпис перших двох, зроблений за допомогою секрету або закритого ключа. Перевірити його може тільки сервер із потрібним ключем. Якщо хтось змінить у payload хоча б один символ, скажімо роль з user на admin, підпис перестане збігатися.
Декодувати — не означає перевірити
Токен, який нормально декодується, каже, що він стверджує, а не те, чи це правда. Ваш бекенд має перевіряти підпис ключем, відхиляти токени з простроченим exp і приймати лише очікувані алгоритми, ніколи не «none». Бібліотеки JWT роблять це за вас; пропустити перевірку — класична вразливість.
Практичні правила
Не кладіть у payload секрети на кшталт паролів: його можна прочитати. Робіть термін дії токенів коротким. Ставтеся до токена як до пароля, поки він дійсний: будь-хто, хто його скопіює, зможе ним користуватися до закінчення терміну.
Де зберігати токен у браузері
Усе, що лежить у localStorage, може прочитати будь-який скрипт на сторінці, тож одна вразливість міжсайтового скриптингу (XSS) здатна розкрити токен. Cookie з прапорцем HttpOnly взагалі недоступна для JavaScript, і цей ризик зникає; доповніть її прапорцями Secure і SameSite та захистом від підробки міжсайтових запитів (CSRF). Ідеального варіанту немає, але для сесійних токенів cookie HttpOnly — безпечніший вибір за замовчуванням.
Термін дії та токени оновлення
JWT не можна «розлогінити» сам по собі: він чинний до моменту exp, якщо тільки сервер не веде список відкликаних токенів. Тому токени доступу зазвичай живуть хвилини, а не дні. Довготриваліший токен оновлення, який зберігають дбайливіше й перевіряють на сервері, дає змогу отримати новий токен доступу, коли старий спливає.
Основні поля одним поглядом
iss видавець хто створив токен
sub суб’єкт користувач чи клієнт, якого він стосується
aud аудиторія який сервіс має його приймати
exp спливає час Unix, після якого він недійсний
nbf не раніше час Unix, до якого він недійсний
iat видано час Unix його створення
Поля часу — це мітки часу Unix у секундах. Сервер має перевіряти не лише exp, а й aud: валідний токен, виданий для одного сервісу, не повинен прийматися іншим.
Як прочитати токен
Декодер JWT від 4Dev розбиває токен на частини й показує header і payload у вигляді читабельного JSON. Він лише декодує і не перевіряє підпис. Токен надсилається на сервер 4Dev для декодування, не логується й не зберігається, але все ж не вставляйте чинні токени з продакшену та відкликайте будь-який токен, який міг витекти.