Pull to refresh

Comments 6

TL/DR. Новички, не делайте так никогда. Автор, мягко говоря, некомпетентен в вопросах, о которых рассуждает.

class JwtConfig

@ConfigurationProperties.

Использование COALESCE в запросе позволяет нам безопасно проверять статус токена: если записи нет в базе - мы по умолчанию считаем такую сессию отозванной.

Вы бы, прежде, чем делать подобные заявления хоть попробовали запросы повыполнять в БД. COALESCE конкретно в данном запросе - ненужная хрень, т.к. поле nullable = false. Если записи, удовлетворяющей условию отбора нет, то будет возвращён пустой набор.

Как в этом случае поведёт себя spring-data-репозиторий, я, честно, не помню, но по JPA специфицикации getSingleResult() при отсутствующей записи бросит NoResultException. Spring-data, скорее всего, как-то обрабатывает этот момент, но вряд ли на пустом наборе он вернёт что-либо, отличающееся от значения по умолчанию для результирующего типа. В данном случае, boolean, а, стало быть, по умолчанию вернётся false, т.о. метод isTokenRevoked() вернёт абсолютно противоположное ожидаемому значение.

JwtAuthenticationFilter extends OncePerRequestFilter ... извлекает токен из заголовка Authorization и "представляется" системе Spring Security

Раз уж затащил этого ~монстра~ Spring Security, то, емнип, там уже всё "из коробки" готово для работы jwt, надо только законфигурить, без какого-либо написания своих компонентов вообще.

И начните уже писать тесты.

Важное уточнение по коду:

Некоторые решения в этой части, в прошлой, и в последующих, например, использование @Value вместо @ConfigurationProperties или отсутствие тестов сделаны сознательно для упрощения разработки и наглядности. Сейчас моя цель собрать и зафиксировать рабочий "скелет" системы. Как только основная логика будет готова, я планирую отдельный этап рефакторинга, где буду закрывать этот "технический долг": переводить конфиги на типизированные классы, исправлять мелкие недочеты в JPA-запросах и покрывать всё тестами.

Про @ConfigurationProperties согласен, это более правильный путь для группировки настроек. В текущем варианте использовал @Value для наглядности в рамках статьи, но для продакшена - однозначно перееду на проперти-классы.

Про COALESCE и пустой результат: Справедливое замечание. Действительно, если записи нет, Spring Data может вернуть false по умолчанию, что даст ложноположительный результат. Это критический момент, буду пересматривать логику на возвращение Optional или проверку через exists.

Про фильтр и "коробочные" решения: Spring Security позволяет многое конфигурировать, но при использовании кастомных Refresh-токенов в БД и специфической логики валидации, свой фильтр дает больше прозрачности и гибкости. Хотя всегда есть куда упрощать.

Сейчас тестировать "чистые" функции генерации строк - это трата времени для прототипа. А вот когда логика обрастет связями, например, сложная ротация токенов или проверка ролей, я сделаю отдельный пост про интеграционное тестирование всего флоу авторизации сразу.

буду закрывать этот "технический долг"

Действительно, зачем делать сразу нормально? А так можно ещё пару недель на рефакторинг списать. Код крутится, лавеха мутится.

свой фильтр дает больше прозрачности и гибкости

А зачем тогда нужен весь Spring Security?

Про рефакторинг: Можно сразу строить космодром, когда нужна просто взлетная полоса для кукурузника. Логичнее сначала подтвердить жизнеспособность архитектуры, а потом её полировать. Это нормальный процесс разработки, а не "списание времени".

Насчет "сделать сразу нормально": попытка вылизать каждую строчку до идеала на этапе набросков часто приводит к оверинжинирингу.

"Сразу правильно может затормозить процесс потому что:

Избыточные абстракции. Трата время на создание универсальных интерфейсов для функций, которые в будущем могут вообще измениться или пойти под нож.

Паралич конфигурации. Вместо того чтобы проверить логику авторизации, можно полдня потратить на возню с иерархией yml-конфигов и @ConfigurationProperties.

Хрупкие тесты: Если покрыть тестами сырой прототип, то при любом изменении логики (которое в начале пути неизбежно) придется переписывать и код, и гору тестов. В итоге работа замедляется вдвое.

Поэтому сейчас важнее проверить жизнеспособность связей между сервисами. А когда архитектура устаканится, можно навести марафет, что в уже стабильном коде будет в разы быстрее и эффективнее, чем переделывать "идеальный" код по несколько раз.

Про Spring Security: Он нужен как мощный каркас - управление сессиями, CORS, CSRF, защита эндпоинтов и иерархия доступов. Написать свой фильтр внутри этого каркаса - это не "изобретение велосипеда", а настройка инструмента под свои задачи, например, хранение Refresh в БД. Одно другому не мешает, а дополняет.

Возможно, вы правы.

Вас тоже благодарю, иногда и я ошибаюсь,

Sign up to leave a comment.

Articles