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

«Кто подписывает JWT токен: сервер (разработчик) или пользователь?» — вопрос из категории Безопасность, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

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