JWT (JSON Web Token) — компактний формат для передачі підписаних даних, найчастіше — інформації про автентифікованого користувача. Токен складається з трьох частин, розділених крапками: header.payload.signature.
Три частини токена
- Header — JSON з типом токена та алгоритмом підпису (наприклад, HS256 чи RS256), закодований у Base64URL.
- Payload — JSON із «claims»: даними про користувача, часом видачі, терміном дії тощо, теж у Base64URL.
- Signature — підпис, обчислений над header і payload за допомогою секретного ключа або приватного ключа, що підтверджує незмінність токена.
Base64URL, а не звичайний Base64
JWT використовує варіант Base64 з URL-безпечним алфавітом: символи + і / замінені на - і _, а заповнювач = зазвичай відкидається. Це дозволяє вставляти токен у URL чи заголовок без додаткового кодування.
Важлива відмінність: декодування ≠ перевірка
Header і payload — це просто Base64URL, тобто будь-хто може декодувати їх і прочитати вміст без жодного ключа. Декодування токена не доводить, що дані не підроблені. Довіряти вмісту токена можна лише після перевірки підпису (signature) за допомогою відповідного ключа — і саме цю перевірку виконує сервер, а не клієнт, що просто дивиться на вміст токена.
Типові сценарії використання
- Швидко подивитись, які дані (claims) закодовані в токені під час налагодження.
- Перевірити термін дії токена (
exp) без звернення до бекенду. - Зрозуміти, яким алгоритмом підписано токен, перед інтеграцією з API.
Небезпечна атака: підміна алгоритму на «none»
Специфікація JWT дозволяє алгоритм none — токен без підпису. Якщо бекенд наївно довіряє полю alg із заголовка токена замість того, щоб перевіряти підпис фіксованим, заздалегідь відомим алгоритмом, зловмисник може підмінити alg на none, прибрати підпис і токен пройде перевірку з довільними даними. Надійні бібліотеки JWT вимагають явно вказати очікуваний алгоритм при верифікації саме для захисту від цієї атаки.