Dj-rest-auth: ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION не работает
Я использую dj-rest-auth, allauth и простой jwt для реализации аутентификации.
В django-allauth установка ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION=True приведет к автоматическому входу пользователя в систему после проверки электронной почты. Но постинг ключа в "/dj-rest-auth/registration/verify-email/" возвращает только {"detail": "ok"}.
Приведенный ниже исходный код объясняет, почему:
# allauth
class ConfirmEmailView(TemplateResponseMixin, LogoutFunctionalityMixin, View):
# ...
def post(self, *args, **kwargs):
# ...
if app_settings.LOGIN_ON_EMAIL_CONFIRMATION:
resp = self.login_on_confirm(confirmation)
if resp is not None:
return resp # this is a HttpResponseRedirect object
# ...
# dj-rest-auth
class VerifyEmailView(APIView, ConfirmEmailView):
# ...
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.kwargs['key'] = serializer.validated_data['key']
confirmation = self.get_object()
confirmation.confirm(self.request)
return Response({'detail': _('ok')}, status=status.HTTP_200_OK)
Поскольку я использую JWT, как я могу переопределить это представление для входа пользователя в систему после проверки и возврата кода доступа?
Вы должны взять этот объект подтверждения, написать confirmation.email_address
, который является объектом модели django-allauth EmailAddress, затем получить пользователя (т.е. вашу модель User). В общем, просто сделайте confirmation.email_address.user
. Наконец, сгенерируйте JWT из объекта user.
Чтобы сгенерировать правильный JSON-ответ, инстанцируйте класс LoginView, установите атрибут класса пользователя, сделав view = LoginView(); view.user = confirmation.email_address.user; # TODO do view.login() but you need to customize it so that you don't call user
, и возьмите объект Response, сделав LoginView().get_response()
Убедитесь, что вы проверили все крайние случаи, например, если адрес электронной почты не существует и т.д.
Всего:
class CustomVerifyEmailView(VerifyEmailView):
# ...
def post(self, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.kwargs['key'] = serializer.validated_data['key']
confirmation = self.get_object()
confirmation.confirm(self.request)
login_view = LoginView()
login_view.user = confirmation.email_address.user
if getattr(settings, 'REST_USE_JWT', False):
self.access_token, self.refresh_token = jwt_encode(self.user)
else:
self.token = create_token(
self.token_model, self.user,
self.serializer,
)
if getattr(settings, 'REST_SESSION_LOGIN', True):
self.process_login()
return login_view.get_response()
Сообщите нам, если это сработает!
Ссылки:
Я также разместил это в вашей проблеме на GitHub. Так что надеюсь, что все правки, внесенные здесь, будут внесены и там.