Аутентификация и авторизация в Java с помощью JWT Руководство для начинающих
Салимжанов Р.
Введение: зачем нужна безопасность?
Представьте, что вы заходите в банк. Прежде чем получить доступ к своему счёту, вы должны:
- Аутентифицироваться — показать паспорт (доказать, что вы это вы).
- Авторизоваться — получить доступ только к своим операциям (ваши права).
В веб-приложениях всё аналогично:
- Аутентификация — проверка логина/пароля.
- Авторизация — проверка прав доступа к ресурсам.
JWT (JSON Web Token) — это цифровой "пропуск", который выдаётся после успешной аутентификации и используется для авторизации в последующих запросах.
Что такое JWT и как он работает?
Структура JWT:
Header — тип токена и алгоритм шифрования.
Payload — данные пользователя (например, имя и роли).
Signature — подпись, гарантирующая подлинность токена.
Жизненный цикл JWT:
- Пользователь вводит логин/пароль.
- Сервер проверяет данные и генерирует JWT.
- Клиент сохраняет токен (например, в LocalStorage).
- При каждом запросе токен передаётся в заголовке Authorization.
- Сервер проверяет подпись и права доступа.
Реализация JWT в Spring Boot
Рассмотрим пример приложения с:
- Регистрацией/входом
- Защищённым эндпоинтом
- Ролевой моделью
Структура проекта (пакеты и файлы)
Подробный разбор ключевых компонентов
1. AuthController.java (папка controller)
Назначение: Обрабатывает HTTP-запросы для регистрации и входа.
2. User.java (папка model)
Назначение: Сущность пользователя для хранения в БД.
3. Role.java (папка model)
Назначение: Сущность роли для RBAC (Role-Based Access Control).
4. UserRepository.java (папка repository)
Назначение: Интерфейс для работы с таблицей пользователей в БД.
5. RoleRepository.java (папка repository)
Назначение: Интерфейс для работы с ролями.
6. LoginRequest.java (папка dto)
Назначение: Объект для передачи данных входа.
7. RegisterRequest.java (папка dto)
Назначение: Объект для передачи данных регистрации.
8. JwtResponse.java (папка dto)
Назначение: Объект для ответа с JWT-токеном.
9. JwtUtils.java (папка jwt)
Назначение: Генерация и проверка JWT.
10. JwtAuthenticationFilter.java (папка jwt)
Назначение: перехватывает запросы и проверяет JWT.
11. SecurityConfig.java (папка security)
Назначение: настраивает Spring Security.
12. UserDetailsServiceImpl.java (папка security)
Назначение: преобразует нашего User в объект Spring Security.
13. application.properties
Естественно, это пример, не следует в файле хранить jwt.secret , пароли и явки.
Взаимодействие компонентов: Полный цикл
1. Пользователь отправляет POST /api/register
Запрос → AuthController.register()
→ UserRepository.save()
→ PasswordEncoder.encode()
2. Пользователь входит через POST /api/login
Запрос → AuthController.login()
→ AuthenticationManager.authenticate()
→ JwtUtils.generateToken()
3. Пользователь обращается к защищённому эндпоинту /protected
Запрос → JwtAuthenticationFilter:
1. Проверяет заголовок Authorization
2. Извлекает токен
3. JwtUtils.validateToken()
4. UserDetailsServiceImpl.loadUserByUsername()
5. Устанавливает аутентификацию в SecurityContext
→ SecurityConfig разрешает доступ
→ Метод контроллера возвращает данные
Как всё соединяется воедино?
- Spring Security управляет аутентификацией через AuthenticationManager.
- JwtAuthenticationFilter перехватывает каждый запрос и проверяет JWT.
- UserDetailsServiceImpl связывает наших пользователей из БД с Spring Security.
- SecurityConfig определяет, какие URL защищены, а какие доступны всем.
- JwtUtils – «мозг» работы с токенами: создание и проверка.
- AuthController – точка входа для регистрации и входа.
Пример работы для запросов
Регистрация:
Если повторно регистрироваться:
Логин (получение токена):
Доступ к защищенному эндпоинту (с токеном):
Типичные ошибки новичков
- Не использовать HTTPS Токены перехватываются в открытых сетях.
- Хранение секретного ключа в коде Используйте переменные окружения или Vault.
- Долгий срок жизни токена Рекомендуется 15-30 минут. Для продления — используйте refresh-токены.
Заключение
Мы реализовали БАЗОВУЮ систему безопасности с JWT! Помните: безопасность — это процесс, а не разовое действие. Всегда следите за обновлениями зависимостей и используйте современные практики.