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. Так что надеюсь, что все правки, внесенные здесь, будут внесены и там.

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