Какой оптимальный способ организовать процесс авторизации при первом входе, включая установку постоянного пароля и подтверждение через код из SMS и электронной почты?

У меня есть приложение, использующее Spring Boot 3 и Spring Security oauth2 resource server для защиты точек доступа. В рамках бизнес-логики предусмотрено следующее: пользователь в базе данных создается с временным паролем и без email, а логином служит номер телефона. 

При первом входе пользователь вводит логин и временный пароль. Если эти данные верны, ему открывается окно для ввода кода из SMS. После успешного ввода кода отображается экран для установки постоянного пароля. После сохранения нового пароля в базе данных пользователю предлагается ввести email. 

Поскольку это является единым бизнес-процессом, а JWT токен мы выдаем только после успешной авторизации с постоянным паролем, у меня возник вопрос о том, как лучше отслеживать состояние этого бизнес-процесса. У меня есть два варианта: либо сразу выдавать JWT токен без ролей и хранить в нем состояние, либо использовать для этого HttpSession. Я склоняюсь к сессиям, но решил проконсультироваться с более опытными специалистами. 

Могли бы вы дать рекомендации по этому вопросу?
  • 13 февраля 2025 г. 7:14
Ответы на вопрос 1
Для реализации процесса авторизации при первом входе, как вы описали, важно учесть не только удобство для пользователя, но и безопасность всей операции. Ваш подход с использованием временного пароля и подтверждением через SMS и email выглядит разумно. Теперь давайте обсудим, каким образом лучше организовать отслеживание состояния этого процесса.

### Ваши два варианта:

1. **JWT токен без ролей с хранением состояния**:
    - Этот подход на первый взгляд удобен, так как JWT токен можно использовать на стороне клиента, и состояние можно управлять через его payload. Однако, у JWT есть особенности:
        - JWT токены, как правило, подписываются и могут быть проверены на стороне сервера. Если вы добавите в payload состояние процесса, тем самым сможете получить определенные ограничения по времени. Если состояние меняется, вам нужно будет убедиться, что старые токены больше не действительны.
        - Также это усложняет процесс обновления состояния, так как для изменения состояния вам, возможно, придется выпускать новый токен. 
        - Если такой токен украден, злоумышленник сможет его использовать, пока он действителен, что может создать уязвимость в процессе, связанном с авторизацией.

2. **Использование HttpSession**:
    - Этот способ более стандартен для работы с пользовательскими сессиями в веб-приложениях.
        - Вам будет легче управлять состоянием процесса, так как вы можете хранить промежуточные данные в атрибутах сессии и обновлять их по мере прохождения пользователем этапов авторизации.
        - Во-первых, сессии хранятся на сервере, и это уменьшает риски, связанные с компрометацией данных.
        - Во-вторых, при использовании сессий вы избежите необходимости беспокоиться о времени действия токенов и о том, что пользователь может получить доступ к защищенным частям приложения, завершив процесс авторизации только частично.

### Рекомендации

1. **Используйте HttpSession для отслеживания процесса авторизации**:
    - Создайте сессию, когда пользователь начинает процесс авторизации, и храните в ней необходимые данные (например, состояние процесса, временный пароль, флаг успешной верификации SMS и т. д.).
    - После того как пользователь успешно изменит пароль и зарегистрирует email, вы можете создать JWT токен и передать его пользователю.

2. **Реализуйте механизмы безопасности**:
    - Убедитесь, что при каждом этапе происходит проверка времени сессии и действия пользователя (например, идентифицируйте стандартные уязвимости типа CSRF, XSS и т.д.).
    - Реализуйте меры по защите от брутфорс-атак как для временного пароля, так и для верификационного кода SMS.

3. **Завершение процесса**:
    - После того как пользователь успешно пройдет все стадии и создаст постоянный пароль, завершите сессию или обновите ее, чтобы включить новую информацию об аутентификации, и выведите JWT токен, который даст ему доступ к защищенным данным.

Этот подход обеспечит простоту в управлении состоянием и повысит безопасность вашего приложения.
Похожие вопросы