Что такое JWT

Ответ

JWT (JSON Web Token) — это компактный и самодостаточный способ передачи информации между сторонами в виде JSON-объекта. Он состоит из трех частей, разделенных точками:

  1. Header — содержит тип токена и алгоритм шифрования (например, HMAC SHA256).
  2. Payload — данные (например, user ID, роли, срок действия).
  3. Signature — подпись для проверки подлинности токена.

Пример структуры:

// Header
{
  "alg": "HS256",
  "typ": "JWT"
}

// Payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Используется для аутентификации и обмена данными. После успешного входа сервер генерирует JWT и отправляет клиенту. Клиент сохраняет токен (например, в localStorage) и отправляет его в заголовке Authorization: Bearer <token> при последующих запросах.

Плюсы:

  • Не требует хранения состояния на сервере (stateless).
  • Можно подписать (JWS) или зашифровать (JWE).

Минусы:

  • Если токен украден, злоумышленник может им воспользоваться (нужны короткие сроки жизни + refresh-токены).
  • Размер больше, чем у session ID.

Пример кода для создания/верификации (Node.js + библиотека jsonwebtoken):

const jwt = require('jsonwebtoken');
const token = jwt.sign({ userId: 123 }, 'secret-key', { expiresIn: '1h' });
const decoded = jwt.verify(token, 'secret-key'); // throws error if invalid

Ответ 18+ 🔞

А, JWT, ёпта, ну это ж классика, как Герасим с Муму, только без утопления, блядь! Слушай, сейчас разжую, как для немого, только словами.

Представь, что тебе нужно передать записку через всю хату, но так, чтобы все видели, а прочитать мог только тот, у кого есть волшебный ключ. Вот JWT — это и есть такая записка, только цифровая, сука.

Состоит из трёх кусков, склеенных точками, как будто кто-то бисер на нитку нанизал, только бисер этот — закодированный текст, блядь.

  1. Заголовок (Header). Тут написано, что это за хуйня и как её проверять. Типа: «Чувак, это JWT, и подписано оно алгоритмом HS256, не ищи подвоха». Всё в формате JSON, просто потом закодировано в Base64URL.
  2. Тело (Payload). А вот тут самое вкусное, блядь! Вся суть послания. Кто пользователь (sub), как зовут, когда выпустили (iat), когда протухнет (exp). Можно пихать что угодно, но только не секреты, потому что это, сука, как открытка — в принципе, прочитать может любой, кто её достанет. Просто так, в открытую, блядь. Поэтому пароли или номера карт — ни-ни, ёпта.
  3. Подпись (Signature). А вот это уже серьёзно. Берут заголовок и тело, склеивают, и ебут их об стол с помощью секретного ключа (или приватного, если RSA) через выбранный алгоритм. Получается магическая строка. Если кто-то попробует в теле что-то поменять хоть на одну букву — подпись не сойдётся, и весь токен нахуй не годен. Как печать на документе, только цифровая.

Как этим пользуются? Очень просто, блядь:

  1. Ты логинишься, сервер проверяет логин-пароль.
  2. Если всё ок, он не создаёт тебе сессию где-то у себя в подвале, а говорит: «На, мудила, вот твой пропускной билет (JWT), вали отсюда». И генерирует этот токен.
  3. Ты, такой довольный, кладёшь его себе в localStorage (что, в общем-то, небезопасно, но об этом позже).
  4. Дальше, когда тебе нужно что-то запросить с сервера, ты несешь этот токен в заголовке запроса: Authorization: Bearer <твой_длинный_токен_тут>.
  5. Сервер, получив его, проверяет подпись. Если подпись верная — значит, токен выпустил он сам, и можно доверять данным внутри. Смотрит, не протух ли (exp), и выдает тебе запрошенные данные. Всё, stateful-хуйни никакой, серверу не нужно помнить о тебе, он просто верит подписи. Красота, блядь!

Плюсы, сука:

  • Stateless. Серверу похуй, он не хранит сессии. Масштабируется легко, как резиновый.
  • Универсальный. Можно запихнуть любые данные. И подписать (JWS), и зашифровать (JWE), если совсем параноик.

Минусы, а куда без них, блядь:

  • Украли токен — всё, пиздец. Злоумышленник может им пользоваться, пока тот не протухнет. Поэтому срок жизни делают коротким, как сигаретный окурок, а для обновления используют отдельные, долгоживущие refresh-токены. Это как основная дверь и чёрный ход, ёпта.
  • Отозвать нельзя. Ну, почти. Раз сервер его не помнит, то и отозвать не может, пока срок не истечёт. Приходится выкручиваться чёрными списками или менять секретный ключ, а это уже овердохуища проблем.
  • Размер. Он больше, чем просто session ID. В каждый запрос тащить такую простыню — не очень экономично.

Ну и, собственно, как это выглядит в коде, на примере Node.js с библиотекой jsonwebtoken:

const jwt = require('jsonwebtoken');
const SECRET_KEY = 'moi-tajnyi-kluch'; // Храни это, блядь, не в коде, а в переменных окружения, ёпта!

// Создаём токен. 'userId' — это наши данные в payload.
const token = jwt.sign({ userId: 123 }, SECRET_KEY, { expiresIn: '1h' });
console.log('Вот твой токен, не потеряй:', token);

// Проверяем токен. Если подпись левая или срок вышел — вылетит ошибка.
try {
  const decoded = jwt.verify(token, SECRET_KEY);
  console.log('Всё ок, данные из токена:', decoded);
} catch (err) {
  console.error('Ой, ёбта, токен невалидный!', err.message);
}

Вот и вся магия, блядь. Инструмент мощный, но как топором — можно дом построить, а можно себе по ебалу получить, если неаккуратно. Главное — короткие сроки, HTTPS везде и не светить refresh-токенами куда попало. А то будет как в той истории, только топить будут не собачку, а всю твою систему безопасности, в рот меня чих-пых!