Django SimpleJWT: Некоторые вопросы по аутентификации с помощью токенов

Я реализую аутентификацию в Django, используя SimpleJWT, и у меня есть несколько вопросов по этому поводу. Для примера, у меня есть несколько доменов с моим бэкендом, некоторые с обычным логином (имя пользователя и пароль), а некоторые с SSO логинами.

Вопрос 1: Для обычного входа в систему я передаю имя пользователя и пароль в полезной нагрузке API TokenObtainPairView, и он дает мне токены доступа и обновления. Как я могу получить токены доступа и обновления при SSO-логине, поскольку он не имеет пароля?

Вопрос 2: Предположим, я храню токены доступа в локальном хранилище и отправляю токен доступа всем API, а также обновляю его до истечения срока действия. Но что произойдет, если пользователь закроет браузер, а мы не сможем обновить маркер доступа. Срок действия маркера доступа истечет, и пользователь выйдет из системы. Как мы можем сохранить вход пользователя в систему в течение определенного времени (скажем, 30 дней)?

Вопрос 3: Имя пользователя и пароль, переданные в полезной нагрузке, видны в curl, является ли это проблемой безопасности? Как я могу с этим справиться?

Для вопроса 2 добавьте этот код в файл settings.py

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(days=30),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=30),
}

Когда срок действия маркера доступа истекает, вы используете маркер Refresh для получения нового маркера доступа.

Это работает потому, что токен Refresh имеет длительный срок службы, обычно до 30 дней (но при желании может быть и дольше).

Пример:

  • Пользователь закрывает браузер
  • Возвращается через 10 дней
  • Пользователь посылает запрос на сервер
  • Сервер вернет ответ 401 Unauthorized, потому что срок действия маркера доступа истек
  • Ваше приложение отправит запрос на получение нового маркера доступа, используя маркер Refresh
  • .
  • Если токен Refresh действителен, сервер вернет новый токен Access
  • .
  • Если срок действия маркера Refresh истек, сервер вернет ответ 401. Это означает, что пользователю необходимо снова войти в систему.

Соображения безопасности

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

Поскольку токен Refresh является действительно мощным, не рекомендуется хранить его в браузере. Так где же вы его храните? И вот тогда эта вводящая в заблуждение идея о "безбэкендовых" веб-сервисах на основе JWT начинает распадаться на части.

Парадоксы, касающиеся хранения токенов:

  1. Храните его в localstorage: Уязвимость для XSS-атак.
    . Это действительно серьезно, потому что XSS-уязвимости могут исходить и от сторонних JS-библиотек, а не только от вашего собственного кода. Хакеры могут взломать стороннюю библиотеку на NPM для внедрения вредоносного кода, и вы можете неосознанно использовать ее в своем проекте (она может быть зависимостью от другой зависимости...).

    .
  2. Хранить в куках httponly: безопасно для XSS-атак, но требует наличия стороннего бэкенд-сервера (потому что сторонние auth-серверы не могут устанавливать куки для другого домена).
    . Если вы задумаетесь об этом, то заметите, что этот случай в точности похож на обычный session auth, когда токен сессии сохраняется в cookie. Так почему бы просто не использовать session auth вместо этой сложной настройки JWT?

Я хочу посоветовать вам тщательно изучить этот вопрос и решить, действительно ли вам нужен JWT для ваших веб-приложений.

Вернуться на верх