Кто подписывает JWT токен: сервер (разработчик) или пользователь?

Ответ

JWT (JSON Web Token) всегда подписывается сервером (разработчиком приложения или сервисом аутентификации), а не пользователем.

Как это работает:

  1. После успешной аутентификации (например, по логину/паролю) сервер создает JWT, содержащий полезные данные (claims).
  2. Сервер подписывает токен, используя секретный ключ (алгоритм HMAC, например, HS256) или пару приватный/публичный ключ (алгоритм RSA, например, RS256).
  3. Подписанный токен отправляется клиенту (пользователю).
  4. Клиент отправляет этот токен при последующих запросах.
  5. Сервер проверяет подпись токена, чтобы убедиться, что он был выдан этим сервером и не был изменен.

Пример создания подписанного JWT на сервере (с использованием библиотеки jjwt):

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

// Секретный ключ, известный только серверу
String secretKey = "mySuperSecretKey";

// Создание подписанного JWT
String jws = Jwts.builder()
    .setSubject("user123")          // claim (полезные данные)
    .claim("role", "ADMIN")        // еще один claim
    .signWith(SignatureAlgorithm.HS256, secretKey.getBytes()) // ПОДПИСЬ сервером
    .compact(); // Результат: xxxxx.yyyyy.zzzzz

Почему не пользователь? Цель подписи — гарантировать целостность и аутентичность токена. Если бы пользователь подписывал токен, он мог бы его подделать. Сервер, как доверенная сторона, подтверждает подписью, что данные внутри токена валидны и были им выпущены.

Ответ 18+ 🔞

Давай разжую эту тему, как будто я тебе её на кухне с пивом объясняю. Смотри, тут народ частенько пиздит про JWT, мол, пользователь его подписывает. Ну, блядь, полный пиздец! Это же как сказать, что ты сам себе в паспорте печать МВД ставишь — нихуя не выйдет.

Вот смотри, как жизнь устроена, ёпта. Представь, ты заваливаешься в бар (это наш сервер). Ты говоришь бармену: «Давай вискарь». А он тебе: «Паспорт покажи, или деньги вперёд». Ты предъявляешь корочки. Бармен (сервер, блядь!) смотрит, кивает, и он сам, сука, ставит тебе на лбу штамп «ПИЛ — ОПЛАЧЕНО». Это и есть подпись, ёбана! Ты же не можешь сам себе этот штамп нарисовать — тебя потом выебут нахуй при попытке получить второй стакан.

Как это по-человечески работает:

  1. Ты лезешь на сервер (логин/пароль, через гугл — неважно). Главное — доказал, что ты не верблюд.
  2. Сервер, довольный тобой, берёт и пишет бумажку (JWT). Типа, «так, этот чувак — user123, он у нас админ, пускайте его везде».
  3. А теперь самое главное, ёбта! Сервер подписывает эту бумажку своим секретным ключом. Это как та самая печать в паспорте или штамп на лбу. Без неё бумажка — просто хуйня, никому не нужная макулатура.
  4. Тебе эту бумажку со штампом выдают. Ты её (токен) суёшь в карман.
  5. Потом ты приходишь к охране (другой endpoint сервера) и говоришь: «Пустите, я админ». Охрана смотрит: бумажка есть? Есть. А штамп (подпись) наш, родной, не подделан? Ага, всё чётко. Значит, проходи, user123.

Вот тебе пример, как сервер эту хрень штампует (на Java, с библиотекой jjwt):

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

// Секретный ключ, который сервер прячет, как золото. Пользователь его НЕ ЗНАЕТ!
String secretKey = "mySuperSecretKey";

// Сервер создаёт и ПОДПИСЫВАЕТ токен
String jws = Jwts.builder()
    .setSubject("user123")          // Кто ты есть
    .claim("role", "ADMIN")        // И чем тебе можно заниматься
    .signWith(SignatureAlgorithm.HS256, secretKey.getBytes()) // ВОТ ЭТО — ПОДПИСЬ СЕРВЕРА! Без этого — пшик.
    .compact(); // И получается эта самая строка xxxxx.yyyyy.zzzzz

А теперь, блядь, почему пользователь этого сделать не может? Да потому что вся хуйня в доверии! Если бы ты сам себе мог ставить штамп «АДМИН», то любой долбоёб стал бы богом в системе за пять секунд. Сервер подписывает — значит, он ручается, что данные внутри проверены и настоящие. Это как гарантия, ёпта. Без неё JWT — просто три куска строки, ни хуя не стоящие.

Короче, запомни раз и нахуй: JWT всегда подписывает тот, кто его выпускает (сервер), а не тот, кто его носит (клиент). Всё остальное — от лукавого и от непонимания базовых принципов, блядь.