← Назад к вопросам

В чем разница между JWT и сессией?

2.2 Middle🔥 271 комментариев
#REST API и микросервисы#Безопасность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# JWT vs Сессия: Полное Сравнение

JWT (JSON Web Token) и сессия — два основных подхода к аутентификации в веб-приложениях. Каждый имеет свои преимущества и недостатки.

Что такое сессия

Механизм работы

Сессия — это сохраненное на сервере состояние пользователя. Процесс:

  1. Пользователь логинится с паролем
  2. Сервер создает сессию (уникальный ID) и сохраняет её в памяти/БД
  3. Сервер отправляет cookie с session ID клиенту
  4. Клиент автоматически отправляет cookie при каждом запросе
  5. Сервер ищет сессию по ID и проверяет её существование

Пример на Spring Security

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
    Authentication auth = authenticationManager.authenticate(
        new UsernamePasswordAuthenticationToken(
            request.getUsername(),
            request.getPassword()
        )
    );
    SecurityContextHolder.getContext().setAuthentication(auth);
    // Spring автоматически создает сессию
    return ResponseEntity.ok("Logged in");
}

@GetMapping("/profile")
public ResponseEntity<?> getProfile() {
    // Spring проверяет сессию автоматически
    User user = (User) SecurityContextHolder.getContext()
        .getAuthentication().getPrincipal();
    return ResponseEntity.ok(user);
}

Что такое JWT

Механизм работы

JWT — это зашифрованный самодостаточный токен. Процесс:

  1. Пользователь логинится с паролем
  2. Сервер создает JWT (подписанный токен с данными пользователя)
  3. Сервер отправляет JWT клиенту
  4. Клиент сохраняет в localStorage/sessionStorage и отправляет в заголовке Authorization
  5. Сервер проверяет подпись JWT без обращения к БД

Пример на Spring Security + JWT

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
    Authentication auth = authenticationManager.authenticate(
        new UsernamePasswordAuthenticationToken(
            request.getUsername(),
            request.getPassword()
        )
    );
    
    String token = jwtProvider.generateToken(auth);
    return ResponseEntity.ok(new JwtResponse(token));
}

@GetMapping("/profile")
public ResponseEntity<?> getProfile(
    @RequestHeader("Authorization") String authHeader) {
    
    String token = authHeader.substring(7); // Remove "Bearer "
    if (jwtProvider.validateToken(token)) {
        String username = jwtProvider.getUsername(token);
        User user = userService.findByUsername(username);
        return ResponseEntity.ok(user);
    }
    return ResponseEntity.status(401).build();
}

Структура JWT

JWT состоит из трех частей, разделенных точками: header.payload.signature

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header (Заголовок)

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

Payload (Данные)

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622
}

Signature (Подпись)

HMAC_SHA256(
  base64url(header) + "." + base64url(payload),
  secret_key
)

Сравнительная таблица

КритерийСессияJWT
ХранилищеНа сервере (Memory, DB)На клиенте
МасштабируемостьСложно (нужна общая БД)Легко (stateless)
БезопасностьСильнее (хранится на сервере)Требует HTTPS
Размер данныхМаленький (только ID)Больше (содержит данные)
LogoutПростой (удалить сессию)Сложный (чёрный список токенов)
CSRFУязвимаЗащищена (токен не в cookie)
Мобильные приложенияСложноОтлично подходит
API и микросервисыТребует общего хранилищаИдеально подходит

Практические примеры

Сессия: Монолитное приложение

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .requestMatchers("/login").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
            .and()
            .sessionManagement()
                .sessionFixationProtection(SessionFixationProtection.MIGRATE_SESSION)
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
        return http.build();
    }
}

JWT: Микросервисы и API

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
                .requestMatchers("/api/auth/login").permitAll()
                .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}

Когда что использовать

Используй Сессию когда:

  • Монолитное веб-приложение
  • Классический MVC (JSP, Thymeleaf)
  • Высокие требования к безопасности
  • Нужен простой logout
  • Использование cookies приемлемо

Используй JWT когда:

  • SPA (Single Page Application) на React/Vue
  • Микросервисная архитектура
  • Мобильное приложение (iOS/Android)
  • REST API
  • Кросс-доменные запросы (CORS)
  • Stateless масштабирование нужно

Гибридный подход

Многие приложения используют оба подхода:

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
    // Проверяем пароль
    Authentication auth = authenticationManager.authenticate(...);
    
    // Создаем JWT для фронта
    String jwtToken = jwtProvider.generateToken(auth);
    
    // Создаем сессию для безопасности
    SecurityContextHolder.getContext().setAuthentication(auth);
    
    return ResponseEntity.ok(new LoginResponse(jwtToken));
}

Безопасность

JWT требует:

  • Использование HTTPS (никогда HTTP)
  • Хранение в httpOnly cookie или защищенном localStorage
  • Короткий срок действия (access token: 15 минут)
  • Refresh token для обновления
  • Защита от XSS атак

Сессия требует:

  • httpOnly и Secure флаги на cookie
  • CSRF токен в POST запросах
  • Регулярная ротация session ID
  • Защита от session fixation атак

Заключение

В современной Java разработке часто комбинируют оба подхода: JWT для API и микросервисов, сессии для веб-приложений. Выбор зависит от архитектуры приложения, требований к масштабируемости и типа клиентов.