Ответ
JWT (JSON Web Token) — это самодостаточный токен в формате JSON, содержащий данные (claims) и криптографическую подпись. Он хранится на клиенте и отправляется с каждым запросом, делая сервер stateless.
Сессия на сервере — это состояние, хранимое на сервере (в памяти, БД, Redis). Клиенту выдаётся только идентификатор сессии (Session ID), обычно в cookie. Сервер stateful — проверяет ID и загружает данные сессии.
Сравнительная таблица:
| Аспект | JWT (Stateless) | Сессии (Stateful) |
|---|---|---|
| Хранение состояния | На клиенте (localStorage, cookie) | На сервере |
| Масштабируемость | Высокая, не требует общего хранилища сессий | Требует общего хранилища (например, Redis) для кластера |
| Отзыв токена/сессии | Сложно (нужен blacklist или короткий TTL) | Просто (удалить запись в хранилище) |
| Типичные уязвимости | XSS (при хранении в localStorage) | CSRF (защищается токенами), захват сессии |
| Размер данных | Увеличивается с каждым claim | Маленький ID, данные на сервере |
Пример JWT в Java (с библиотекой jjwt):
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
// Создание токена
String jwt = Jwts.builder()
.setSubject("user123")
.claim("role", "ADMIN")
.signWith(SignatureAlgorithm.HS256, "secretKey")
.compact();
// Клиент отправляет токен в заголовке: `Authorization: Bearer <jwt>`
Пример работы с сессией в Java Servlet:
// Создание сессии
HttpSession session = request.getSession(true);
session.setAttribute("userId", "user123");
// Получение данных
String userId = (String) session.getAttribute("userId");
Выбор подхода: JWT идеален для распределённых систем и мобильных приложений. Сессии — для традиционных веб-приложений с контролируемой средой, где нужен мгновенный отзыв доступа.
Ответ 18+ 🔞
Да ты посмотри, какая хуйня придумана, блядь! Вот сидишь ты, такой весь из себя архитектор, и думаешь: как бы так пользователя помнить, но чтобы серверу не запариваться? И тут тебе на выбор — два классических пиздеца.
JWT — это типа такая бумажка, самодостаточная, блядь. Всё, что надо, в неё впихнули: кто ты, на что имеешь право, и подпись, чтобы не подделали, сука. Хранится эта хуйня у клиента, а с каждым запросом он её, как пропуск, предъявляет. Серверу делать нихуя — проверил подпись, вытащил данные и всё. Stateless, ёпта! Без состояния, как младенец.
Сессия на сервере — это уже классика жанра, старый добрый бардак. Сервер, сука, помнит. Запоминает тебя в своей памяти, в базе или в Redis. А клиенту суёт только билетик — Session ID, обычно в куки. И каждый раз, когда ты приходишь, сервер бежит проверять: «А, так это же Вася! Поднимаю его данные из хранилища». Stateful, блядь, с состоянием, как баба после сорока.
А вот тебе табличка, чтобы не ебать мозги:
| Шняга | JWT (Без состояния) | Сессии (С состоянием) |
|---|---|---|
| Где хранится вся хуйня | У клиента (localStorage, куки) | На сервере, мать его |
| Масштабируемость | Овердохуищная! Добавляй серверов — им ничего друг о друге знать не надо. | Ну, тут пизда. Для кластера нужно общее хранилище сессий (типа Redis), а то один сервер тебя знает, а другой — нет. |
| Как отозвать доступ | О, это пиздец! Токен живёт сам по себе. Или blacklist заводи (что сводит stateless на нет), или делай срок жизни коротким, как у мотылька. | Да элементарно, Ватсон! Удалил запись из хранилища — и всё, сессия накрылась медным тазом. |
| Чем могут ебнуть | XSS, если хранишь в localStorage — скрипт вытащит твой токен и будет жить твоей жизнью. | CSRF — если куки летят автоматом, то с другого сайта могут от твоего имени запрос послать. И захват сессии, конечно. |
| Размер передаваемого говна | Растёт, как на дрожжах, с каждым новым полем (claim). | Малюсенький ID, а все тяжёлые данные — на серваке. |
Вот, смотри, как JWT на Java слепить (библиотека jjwt):
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
// Делаем токен
String jwt = Jwts.builder()
.setSubject("user123")
.claim("role", "ADMIN")
.signWith(SignatureAlgorithm.HS256, "secretKey")
.compact();
// И клиент потом таскает это в заголовке: `Authorization: Bearer <jwt>`
А вот как с сессией в Servlet'ах возиться:
// Создаём сессию
HttpSession session = request.getSession(true);
session.setAttribute("userId", "user123");
// Достаём данные обратно
String userId = (String) session.getAttribute("userId");
Так что же выбрать, ёпта? Всё просто, как три копейки.
- JWT — твой выбор, если делаешь API для кучи сервисов, мобилу или SPA, где серверам нельзя быть связанными одной судьбой.
- Сессии — бери, если у тебя классическое веб-приложение, где контроль над всем есть, и тебе жизненно важно в любой момент вышвырнуть пользователя нахуй.