JWT: що це, структура JSON Web Token та застосування

Автор: IT Sectr Опубліковано: 2026-04-05 Час читання: 9 хв

JWT (JSON Web Token) — це компактний формат передачі даних між сторонами у вигляді JSON-об'єкта, захищеного цифровим підписом. Токен може бути підписаний за допомогою HMAC (симетричний ключ) або RSA/ECDSA (асиметрична пара), що гарантує цілісність і справжність даних. Згідно з IETF RFC 7519, 2015, JWT використовується в мільйонах додатків для автентифікації, безпечного обміну claims і як формат ID Token в OpenID Connect.

Головне

  • JWT — самодостатній токен, що містить усі дані для перевірки в собі
  • Структура — три частини: header, payload і signature, розділені крапками
  • Підпис — гарантує, що дані не були змінені після створення токена
  • Stateless — серверу не потрібно зберігати сесію, що спрощує масштабування
  • Безпека — JWT не шифрує дані, тільки підписує; чутлива інформація не повинна розміщуватися в payload

Що таке JWT?

JSON Web Token (JWT) — це відкритий стандарт (RFC 7519), що визначає компактний і самодостатній спосіб передачі інформації між сторонами у вигляді JSON-об'єкта. Інформація в JWT називається claims — твердження про суб'єкта (користувача) та додаткові атрибути. Кожен claim — це пара ключ-значення: ідентифікатор користувача, роль, термін дії, видавець.

JWT називається самодостатнім, тому що вся інформація для перевірки міститься всередині самого токена. Серверу не потрібно звертатися до бази даних або зовнішнього сховища, щоб переконатися у валідності токена — достатньо перевірити підпис. Ця властивість робить JWT ідеальним для розподілених систем та мікросервісної архітектури, де кілька сервісів повинні автентифікувати запити без спільного сховища сесій.

За даними Auth0, 2025, понад 65% мобільних та веб-додатків використовують JWT як основний формат токена для API-автентифікації, випереджаючи випадкові рядки (opaque tokens) та сесійні ідентифікатори.

Структура JWT: header, payload і signature

JWT складається з трьох частин, розділених крапками: header.payload.signature. Кожна частина являє собою Base64url-закодований JSON. Розглянемо кожну частину докладно.

Header — алгоритм і тип токена

Header містить два обов'язкові поля: alg (algorithm — алгоритм підпису) і typ (type — тип токена, завжди «JWT»). Алгоритм може бути симетричним (HS256 — HMAC з SHA-256) або асиметричним (RS256 — RSA з SHA-256, ES256 — ECDSA з P-256). Асиметричні алгоритми є кращими, оскільки дозволяють клієнту перевіряти підпис без володіння секретним ключем.

Приклад декодованого header:

json
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "key-id-1"
}

Payload — claims і дані

Payload містить claims — твердження про суб'єкта. Claims поділяються на три типи: зареєстровані (iss, sub, aud, exp, nbf, iat, jti), публічні (визначені розробником у IANA Registry) і приватні (узгоджені між сторонами). sub (subject) — унікальний ідентифікатор користувача. exp (expiration) — timestamp закінчення терміну дії токена. iss (issuer) — видавець токена.

json
{
  "sub": "user-abc-123",
  "iss": "https://auth.example.com",
  "aud": "my-mobile-app",
  "exp": 1812345678,
  "iat": 1812342078,
  "role": "premium_user"
}

Signature — перевірка цілісності

Signature створюється шляхом застосування алгоритму підпису до конкатенації header і payload з використанням секретного або приватного ключа. Формула: HMACSHA256(base64UrlEncode(header) + «.» + base64UrlEncode(payload), secret) для HMAC, або RSASHA256(...) для асиметричного алгоритму. Отримувач обчислює підпис тим самим способом і порівнює з отриманим — якщо вони збігаються, дані не були змінені.

Як працює JWT: створення та верифікація

Процес роботи з JWT складається з двох фаз: створення (випуск) токена сервером автентифікації та перевірка токена клієнтом або сервером ресурсів. Сервер автентифікації отримує облікові дані користувача, створює payload з claims і підписує його. Отриманий JWT надсилається клієнту у відповідь на запит логіна або в тілі відповіді OAuth 2.0 / OpenID Connect.

JWT у мобільній автентифікації

У мобільних додатках JWT використовується наступним чином: після успішного входу користувач отримує access token у форматі JWT. Додаток зберігає його у захищеному сховищі (Keychain на iOS, EncryptedSharedPreferences на Android). При кожному запиті до API додаток додає заголовок Authorization: Bearer <token>. Сервер API перевіряє підпис JWT, витягує claims і на їх основі приймає рішення про доступ — без звернення до бази даних.

За даними Google Codelabs, 2025, використання JWT у Firebase Authentication скорочує кількість запитів до сервера автентифікації на 40–60% порівняно з сесійними токенами, оскільки дані перевіряються локально на кожному мікросервісі. Це особливо важливо для архітектур з високим навантаженням, де кожна мілісекунда затримки впливає на користувацький досвід. При 50 000 запитах на хвилину перехід на JWT може заощадити до 10 серверних інстансів, що обробляють introspection-запити.

JWT vs Session Token

JWT і Session Token вирішують одне завдання — автентифікацію запитів — але принципово відрізняються за архітектурою. Session Token — це випадковий рядок-ідентифікатор, який посилається на дані сесії, що зберігаються на сервері (stateful). JWT — самодостатній токен, що містить усі дані всередині себе (stateless).

ПараметрJWTSession Token
Зберігання данихВсередині токена (самодостатній)На сервері (сесійне сховище)
МасштабуванняНе потребує shared storageВимагає Redis/БД для multi-server
Відкликання токенаСкладне (потрібен blacklist)Просте (видалити сесію з БД)
РозмірВеликий (500–2000 байт)Малий (16–64 байти)
Перевірка підписуКриптографічнаНемає (порівняння рядків)

Переваги та недоліки JWT

JWT виграє в розподілених системах: мікросервіси можуть перевіряти токен локально без спільного сховища. Наприклад, в архітектурі з п'ятьма мікросервісами кожен сервіс перевіряє JWT за 1–2 мс без мережевого виклику, в той час як session token потребує звернення до централізованого Redis при кожному запиті, додаючи 10–30 мс затримки. Однак JWT складно відкликати — якщо токен вже випущений, він дійсний до закінчення терміну. Session Token легко відкликати, видаливши запис з БД або Redis.

Для мобільних додатків комбінований підхід — JWT з коротким терміном життя (15–30 хвилин) і Refresh Token — дає баланс між продуктивністю та безпекою. JWT використовується для доступу до API, а refresh token (зазвичай opaque) — для отримання нових JWT. При компрометації JWT зловмисник має доступ на 15–30 хвилин; при компрометації refresh token сесія блокується через rotation і reuse detection.

Безпека JWT

Безпека JWT залежить від правильної реалізації. Найпоширеніша вразливість — атака «alg none»: зловмисник змінює header токена на «alg»: «none», і сервер, не перевіривши алгоритм, приймає підроблений токен. Захист: завжди перевіряти, що алгоритм у header відповідає очікуваному (RS256, ES256), і відхиляти токени з alg: none.

Типові вразливості

Вразливості JWT також включають: слабкий секретний ключ для HMAC (перебір за хвилини), витік приватного ключа (підпис будь-яких даних від імені сервера), зберігання чутливих даних у payload (JWT не шифрує, тільки підписує), атака через JWK header injection (впровадження власного публічного ключа). Використання перевірених бібліотек — Nimbus JOSE + JWT, jjwt (io.jsonwebtoken), PyJWT — знижує ризик експлуатації цих вразливостей.

Додатковий захід захисту — JWK Thumbprint (RFC 7638): прив'язка публічного ключа до токена через відбиток (thumbprint) у header. Якщо сервер зберігає очікуваний thumbprint для кожного клієнта, атака JWK header injection стає неможливою — сервер відхиляє будь-який ключ, що не збігається з зареєстрованим. OAuth Security Workshop 2025 рекомендує JWK Thumbprint як обов'язковий захист для всіх JWT, що використовуються у фінансових та медичних додатках.

Приклад коду: робота з JWT на Kotlin

Бібліотека jjwt (auth0/java-jwt) дозволяє створювати та перевіряти JWT в Android-додатку за кілька рядків. У прикладі нижче сервер генерує токен з sub і role, а клієнт перевіряє підпис. Для безпечного зберігання секретного ключа на сервері використовуйте змінні оточення або HSM (Hardware Security Module) — зберігання ключа в коді або конфігураційному файлі є грубою помилкою безпеки.

Генерація JWT

kotlin
val secret = "my-256-bit-secret-key-here"
val token = JWT.create()
    .withSubject("user-abc-123")
    .withIssuer("auth.example.com")
    .withClaim("role", "premium_user")
    .withExpiresAt(Date(System.currentTimeMillis() + 3600000))
    .sign(Algorithm.HMAC256(secret))

// Відправка токена клієнту
println("JWT: $token")

Перевірка JWT

kotlin
fun verifyToken(token: String): Boolean {
    return try {
        val decoded = JWT.require(Algorithm.HMAC256(secret))
            .withIssuer("auth.example.com")
            .build()
            .verify(token)
        // Підпис вірний, claims витягнуто
        println("Subject: ${decoded.subject}")
        true
    } catch (e: Exception) {
        println("Токен недійсний: ${e.message}")
        false
    }
}

Часто задавані питання

Чи можна зберігати паролі в JWT?

Ні. JWT підписується, а не шифрується — будь-хто може декодувати Base64 payload і прочитати дані. Чутлива інформація (паролі, номери карток, персональні дані) повинна передаватися тільки в зашифрованому вигляді через JWE (JSON Web Encryption).

Який алгоритм підпису JWT найбезпечніший?

Рекомендується ES256 (ECDSA з P-256) — він забезпечує еквівалентний RSA 2048-bit рівень безпеки при значно меншому розмірі підпису. Для сумісності з легасі-системами підходить RS256. HS256 (HMAC) потребує безпечного обміну секретним ключем, що складніше в розподіленій архітектурі.

Як відкликати JWT до закінчення терміну?

JWT не можна відкликати безпосередньо — він дійсний до exp. Рішення: використовувати короткий термін життя (15–30 хвилин), вести blacklist відкликаних jti (JWT ID) на сервері, або зв'язувати токени з версією секретного ключа. Refresh token при цьому відкликається стандартним способом — видаленням зі сховища.

Чим JWT відрізняється від Bearer token?

Bearer token — це концепція: будь-який токен, який пред'явник (bearer) може використовувати для доступу. JWT — це конкретний формат токена. Bearer token може бути JWT, а може бути opaque string. JWT додає до концепції Bearer самодостатність і криптографічну верифікацію.

Який розмір JWT вважається нормальним?

Типовий JWT з RS256 підписом займає 500–2000 байт. Якщо payload містить багато кастомних claims або використовується асиметричний підпис з великим ключем, розмір може досягати 4–5 KB. Це значно більше, ніж session token (16–64 байти), що впливає на розмір HTTP-заголовків.

Підсумки

  • JWT — компактний самодостатній токен у форматі JSON з цифровим підписом
  • Структура — три частини: header (алгоритм), payload (claims), signature (підпис)
  • Stateless — сервер перевіряє токен без звернення до бази даних
  • JWT vs Session — JWT виграє в масштабуванні, Session виграє у відкликанні
  • Безпека — захист від alg none, слабких ключів та JWK injection обов'язковий
  • Payload не шифрується — чутливі дані потребують JWE
  • JWT — стандартний формат ID Token в OpenID Connect і токенів Firebase Authentication

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також