Как сделать аутентификацию веб-маркера Django JSON, не заставляя пользователя повторно вводить пароль?

В моем приложении Django для проверки подлинности используется Rest Framework JWT. Он отлично работает и очень элегантен.

Однако у меня есть прецедент, который я пытаюсь построить. Я уже закодировал рабочее решение для рабочего процесса "Забыли пароль". Я разрешаю неавторизованному пользователю reset их пароль, если он и только, если они нажимают на секретную ссылку, которую я отправляю на их адрес электронной почты. Однако я хотел бы изменить это решение таким образом, чтобы после успешного завершения рабочего процесса password- reset пользователь автоматически регистрировался без повторного ввода имени пользователя и (нового) пароля. Я хотел бы сделать это, чтобы сделать работу пользователя максимально трением.

Проблема заключается в том, что я не знаю, как сделать эту работу без повторного ввода пользователем пароля (или сохранения его в ясном тексте в БД, что явно очень плохо). Ниже приведен текущий способ получения токена JWT. Вы можете видеть, что в строке # 12 мне нужен пароль для очистки пользователя. У меня его нет. У меня есть только зашифрованный пароль, хранящийся в my_user.password.

Как использовать зашифрованный пароль в my_user.password вместо пароля для получения JWT? Если я не могу его использовать, то как этот рабочий процесс достигается с помощью Rest Framework JWT?

from rest_framework_jwt.views  import ObtainJSONWebToken
from rest_framework status
from django.contrib.auth.models import User

my_user = User.objects.get(pk=1)
ojwt = ObtainJSONWebToken()

if "_mutable" in dir(request.DATA):
    mutable = request.DATA._mutable
    request.DATA._mutable = True
request.DATA['username'] = my_user.username
request.DATA['password'] = "<my_user clear password>"
if "_mutable" in dir(request.DATA):
    request.DATA._mutable = mutable


token_response = ojwt.post(request)
if status.is_success(token_response.status_code):
     # Tell the user login succeeded!!
else:
     # Tell the user login failed.
     # But hopefully, this shouldn't happen

Ответы

Ответ 1

При работе с Django REST Framework JWT обычно ожидается, что пользователь генерирует токен самостоятельно. Поскольку вы генерируете токен от имени пользователя, вы не можете использовать какие-либо стандартные представления, чтобы заставить его работать.

Вам нужно будет генерировать токен самостоятельно, подобно как DRF JWT делает это в представлениях. Это означает, что для вашего кода просмотра используется следующее:

from rest_framework_jwt.settings import api_settings
from datetime import datetime


jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

my_user = User.objects.get(pk=1) # replace with your existing logic

payload = jwt_payload_handler(my_user)

# Include original issued at time for a brand new token,
# to allow token refresh
if api_settings.JWT_ALLOW_REFRESH:
    payload['orig_iat'] = timegm(
        datetime.utcnow().utctimetuple()
    )

return {
    'token': jwt_encode_handler(payload)
}

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