З чого складається JWT
Три частини й дві крапки
JWT — це рядок із трьох частин, склеєних крапками. Перша частина, заголовок, каже, яким алгоритмом токен підписаний. Друга — власне дані: набір пар «ім’я — значення», які називають claims. Третя — підпис.
Перші дві частини це звичайний JSON, записаний у base64url. Тобто будь-хто, хто має токен, читає його вміст без секрету. Підпис не ховає дані, він лише доводить, що їх не міняли по дорозі. Тому в JWT не кладуть пароль, номер карти чи щось, чого не можна показувати.
Що таке claims
Частину імен стандарт закріпив за собою, і саме їх перевіряє чужий код:
- sub — кому виданий токен, зазвичай ідентифікатор користувача; - iss — хто його видав; - aud — який сервіс має його приймати; - iat — момент видачі, у секундах від 1970 року; - exp — момент, після якого токен не приймають.
Решту імен ви придумуєте самі: роль, тариф, ознака доступу. Сторінка складає п’ять названих вище, а все своє ви дописуєте в полі «Власні claims».
Підпис
HS256, HS384 і HS512 — це той самий HMAC з різним хешем усередині. Береться рядок «заголовок.навантаження», рахується HMAC із вашим секретом, результат дописується третьою частиною. Сторона, яка перевіряє токен, рахує те саме тим самим секретом і звіряє результат.
Довший хеш не робить токен надійнішим сам по собі: слабке місце — це короткий секрет, а не HS256. Для секрету беруть випадковий рядок від 32 символів.
Термін дії
exp рахується від моменту видачі плюс термін, який ви вказали. Короткий термін — це не перестраховка: токен не можна відкликати, поки він не прострочився, бо перевіряльник нікуди не ходить за списком скасованих. Година для робочого токена і кілька хвилин для одноразового — звичайна практика.
Часті питання про генератор JWT
Чи можна цим токеном заходити в реальний сервіс?
Тільки якщо сервіс перевіряє підпис тим самим секретом, який ви вписали. Токен складений правильно, але чужий сервіс має свій секрет і ваш підпис не зійдеться.
Чому мій JSON у власних claims не приймається?
Приймається лише об’єкт у фігурних дужках: {"role": "admin"}. Масив, число чи рядок сторінка відмовляє. Імена sub, iss, aud, iat і exp теж відмовляються — їх складає сама сторінка, і два однакові імені в одному JSON означають, що одне з них загубиться.
Чому немає RS256?
RS256 підписують приватним ключем, а не секретом, і ключ довелося б завантажити на сервер. Сторінка складає лише HMAC-токени, де обидві сторони знають один рядок.
Токен прострочився — як його продовжити?
Ніяк. exp усередині підписаної частини, тож зміна дати ламає підпис. Видають новий токен.
Генератор JWT онлайн — підписаний токен за хвилину
Оберіть алгоритм, впишіть секрет — і токен складеться. Решта полів необов’язкові: без них у навантаженні будуть лише iat і exp.
Токен у картці можна скопіювати цілим, а три рядки під ним показують, що саме пішло в кожну частину. Це зручно, коли чужий сервіс відмовляє токену й треба подивитись, які claims у ньому насправді.
Секрет іде на сервер у запиті, тому тут вписують тестовий, а не робочий.