JWT. Часть 3 — Как работает подпись В прошлой части мы выяснили важную вещь: Payload обычного JWT не шифруется. Он кодируется через Base64URL, а это не шифрование. То есть содержимое Payload может прочитать любой, у кого есть сам токен. Например, внутри JWT может быть: { "sub": "42", "role": "USER" } Пользователь может декодировать Payload и увидеть эти данные. 🤚Именно поэтому внутрь JWT нельзя класть: пароли секретные ключи данные банковских карт другую информацию, которую пользователь не должен видеть Но тогда возникает логичный вопрос: Если Payload можно прочитать, что мешает пользователю изменить USER на ADMIN ? Например: { "sub": "42", "role": "ADMIN" } Сам Payload изменить технически можно. Но после этого токен перестанет проходить проверку. Почему? Потому что третья часть JWT — это: SIGNATURE То есть подпись. Упрощённо JWT создаётся так. Сначала сервер берёт: HEADER + PAYLOAD Получается что-то вроде: header.payload После этого сервер вычисляет криптографическую подпись. Упрощённо: signature = algorithm( header + "." + payload, key ) В итоге получается: HEADER.PAYLOAD.SIGNATURE Допустим сервер выпустил токен с таким Payload: { "sub": "42", "role": "USER" } И для него была рассчитана подпись: ABC123 Получился JWT: HEADER.PAYLOAD.ABC123 Теперь пользователь меняет: { "role": "USER" } на: { "role": "ADMIN" } Но старая подпись ABC123 была рассчитана для старого содержимого. Для нового Payload правильная подпись уже будет другой. Условно: старый payload → ABC123

новый payload → XYZ789 Пользователь не знает ключ, которым сервер создаёт правильную подпись. Поэтому подделать корректную SIGNATURE он не может. Когда Backend получает JWT, он не должен просто прочитать Payload. Он должен выполнить проверку: получили JWT ↓ разобрали HEADER и PAYLOAD ↓ проверили SIGNATURE ↓ проверили срок действия ↓ только после этого доверяем claims Например, если злоумышленник изменит: { "role": "USER" } на: { "role": "ADMIN" } сервер при проверке увидит: signature invalid и отклонит запрос. И здесь есть очень важный момент. JWT обычно защищает данные от изменения, а не от чтения. То есть: Payload можно прочитать ↓ Payload можно попытаться изменить ↓ Но незаметно изменить его нельзя, потому что сломается подпись Плохая реализация: получили JWT ↓ декодировали ↓ увидели role = ADMIN ↓ дали права администратора Так делать нельзя. Правильная логика: получили JWT ↓ проверили подпись ↓ проверили claims ↓ токен валиден? ↓ только тогда используем role То есть сама возможность декодировать JWT ещё ничего не доказывает. Доверять данным можно только после проверки токена. Если вернуться к аналогии с пропуском: PAYLOAD — это информация, написанная на пропуске. Её можно увидеть: Имя: Дмитрий Роль: EMPLOYEE А SIGNATURE — это защита от подделки. Ты можешь попытаться изменить: Роль: EMPLOYEE на: Роль: DIRECTOR Но проверка покажет, что пропуск был изменён. Теперь остаётся следующий вопрос: Каким именно ключом создаётся подпись и как другие сервисы её проверяют? Потому что есть два популярных подхода: HS256 RS256 И работают они по-разному. В следующей части разберём симметричную и асимметричную подпись JWT простым языком.🔞