Коли ви входите в сучасну односторінкову програму (наприклад, React або Vue) або мобільну програму, серверу потрібен спосіб запам’ятати, хто ви є. Традиційно це робилося, зберігаючи «ідентифікатор сеансу» у величезній базі даних на сервері та скидаючи файл cookie у ваш браузер. Щоразу, коли ви натискаєте кнопку, сервер повинен шукати цей ідентифікатор у своїй базі даних. Це називається автентифікацією з урахуванням стану.
Однак в епоху мікросервісів і хмарного масштабування бази даних стали вузьким місцем. Щоб вирішити цю проблему, розробники застосували Stateless Authentication через JSON Web Tokens (JWT). Завдяки JWT серверу не потрібно запам’ятовувати, хто ви — ваш браузер повідомляє серверу, хто ви, і використовує криптографію, щоб підтвердити це.
Анатомія JWT
Якщо ви перевіряєте мережевий трафік після входу в сучасну програму, ви, ймовірно, побачите заголовок «Авторизація: носій», за яким слідує довгий довільний рядок символів, розділених двома крапками. Це JWT.
JWT складається саме з трьох частин: Header.Payload.Signature.
1. Заголовок
Перша частина — це об’єкт JSON у кодуванні Base64URL, який просто описує маркер. Зазвичай він містить дві властивості: тип маркера (JWT) і використовуваний алгоритм підпису (наприклад, HMAC SHA256 або RSA).
2. Корисне навантаження (претензії)
Середня частина також є об’єктом JSON у кодуванні Base64URL. Саме тут живуть фактичні дані. Ці фрагменти даних називаються "претензіями". Наприклад, він може містити ваш ідентифікатор користувача, вашу роль (наприклад, «Адміністратор») і мітку часу закінчення терміну дії. Оскільки це корисне навантаження додається до кожного запиту, сервер миттєво дізнається, хто ви, без запиту до бази даних.
КРИТИЧНЕ ПОПЕРЕДЖЕННЯ: корисне навантаження лише закодовано, не зашифровано. Кожен, хто перехопить JWT, може легко його декодувати та прочитати корисне навантаження. Ніколи не зберігайте паролі, номери соціального страхування або конфіденційні дані в корисному навантаженні JWT.
3. Підпис
Якщо будь-хто може читати та редагувати корисне навантаження, що заважає зловмисному користувачеві змінити свою роль із «Користувача» на «Адміністратор»? Відповідь - Підпис.
Щоб створити підпис, сервер бере заголовок, корисне навантаження та високобезпечний секретний ключ (відомий лише серверу) і запускає їх за допомогою криптографічного алгоритму (наприклад, SHA256). Отриманий хеш стає підписом.
Коли сервер отримує маркер назад від клієнта, він перераховує підпис за допомогою свого секретного ключа. Якщо користувач втрутився в корисне навантаження (навіть змінивши одну букву), перерахований підпис не збігатиметься з підписом на токені, і сервер миттєво відхилить запит як шахрайський.
Безпечно перевіряйте жетони
Потрібно прочитати корисне навантаження JWT, щоб налагодити програму? Використовуйте наш офлайн-декодер JWT, щоб миттєво перевіряти заявки, не надсилаючи конфіденційний маркер на віддалений сервер.
Відкрийте декодер JWTЧому мікросервіси люблять JWT
Уявіть собі таку компанію, як Netflix. У них є сервер автентифікації, сервер потокового відео та сервер виставлення рахунків. Якби вони використовували традиційні сеанси, кожен окремий сервер мав би постійно спілкуватися з центральною базою даних, щоб перевірити, чи ввійшов користувач.
За допомогою JWT сервер автентифікації підписує маркер за допомогою закритого ключа. Потім користувач передає цей маркер безпосередньо на відеосервер. Оскільки відеосервер має відкритий ключ, він може самостійно перевіряти підпис. Відеосервер точно знає, хто є користувачем, навіть не звертаючись до сервера автентифікації чи бази даних. Це дозволяє інфраструктурі нескінченно масштабуватися без вузьких місць.
Темна сторона: недійсність маркера
JWT не ідеальні. Їхня найбільша сила (те, що вони не мають громадянства) є також і найбільшою слабкістю. Оскільки сервер не зберігає записи про активні маркери, ви не можете легко вийти з системи або зробити певний маркер недійсним до закінчення терміну його дії.
Якщо хакер викраде JWT користувача, він матиме повний доступ, доки не закінчиться мітка терміну дії маркера. Щоб зменшити цей ризик, інженери безпеки використовують систему з двома маркерами:
- Маркери доступу: короткочасні JWT (наприклад, 15 хвилин), які використовуються для запитів API.
- Маркери оновлення: надійно зберігаються довгострокові токени зі збереженням стану, які використовуються лише для запиту нових маркерів доступу. Якщо обліковий запис зламано, сервер відкликає токен оновлення, і токен доступу хакера природним чином помре через 15 хвилин.
Часті запитання (FAQ)
Де я маю зберігати JWT на інтерфейсі?
Зберігання JWT у localStorage робить їх уразливими до атак міжсайтового сценарію (XSS). Найбезпечнішим місцем для зберігання JWT у веб-переглядачі є файл cookie HttpOnly, який запобігає доступу JavaScript до нього.
Що станеться, якщо станеться витік секретного ключа мого сервера?
Катастрофа. Якщо хакер отримує ваш секретний ключ HMAC або закритий ключ RSA, він може створити дійсні JWT з будь-яким корисним навантаженням, яке забажає. Вони можуть створювати маркери, надаючи собі права суперадміністратора, і ваш сервер прийме їх як дійсні. Ви повинні негайно повернути свої ключі.
Чи JWT швидші за файли cookie сеансу?
Не обов'язково. JWT мають значно більший розмір файлу, ніж 32-символьний ідентифікатор сеансу, тобто вони споживають більше пропускної здатності мережі на кожен запит. Їхня перевага у швидкості повністю пов’язана з обходом пошуку бази даних на сервері.