RytRyu-0817
@RytRyu-0817

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

django-allauthの本登録をメール内のリンクでgetメソッドで行いたい。

解決したいこと

現在django-rest-frameworkでallauthを使って認証周りを作っています。
<使用ライブラリ>
dj-rest-auth==5.0.1
Django==4.2.6
django-allauth==0.58.1
djangorestframework==3.14.0

新規登録の流れは以下のようなものです。

①メアド、パスワードを入力(仮登録)
②メアドにメールが届き、リンクを踏む
③識別キー入力
④本登録完了

やりたいのは、以下画像のようなキー入力をする工程(キーをpostする)をなくして、メールのリンクを踏んだらすぐに本登録を完了にしたいです。
2023-11-02.png

自分で試したこと

以下のallauthのドキュメントでACCOUNT_CONFIRM_EMAIL_ON_GET(リンクをgetリクエストで自動確認)のパラメータをsettings.pyでtrueにしたのですが、思うように動きません。
https://docs.allauth.org/en/latest/account/configuration.html

コード部分

app.urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('mdeditor/', include('mdeditor.urls')),
    path('api/', include("sharefolio.urls")),
    path('auth/', include('dj_rest_auth.urls')),
    path('auth/registration/', include('dj_rest_auth.registration.urls')),
    #メール内のリンク部分 verifyEmailViewはdj-rest.authのもの
    re_path(
        r'auth/account-confirm-email/(?P<key>[-:\w]+)/$', VerifyEmailView.as_view(),
        name='account_confirm_email',
    ),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

VerifyEmailView内

class VerifyEmailView(APIView, ConfirmEmailView):
    permission_classes = (AllowAny,)
    allowed_methods = ('POST', 'OPTIONS', 'HEAD')

    def get_serializer(self, *args, **kwargs):
        return VerifyEmailSerializer(*args, **kwargs)

    def get(self, *args, **kwargs):
        raise MethodNotAllowed('GET')

    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)

ConfirmEmailView(VerifyEmailViewの継承先)

class ConfirmEmailView(TemplateResponseMixin, LogoutFunctionalityMixin, View):
    template_name = "account/email_confirm." + app_settings.TEMPLATE_EXTENSION

    def get(self, *args, **kwargs):
        print("kkk")
        try:
            self.object = self.get_object()
            if app_settings.CONFIRM_EMAIL_ON_GET:
                return self.post(*args, **kwargs)
        except Http404:
            self.object = None
        ctx = self.get_context_data()
        return self.render_to_response(ctx)

    def post(self, *args, **kwargs):
        self.object = confirmation = self.get_object()
        email_address = confirmation.confirm(self.request)
        if not email_address:
            get_adapter(self.request).add_message(
                self.request,
                messages.ERROR,
                "account/messages/email_confirmation_failed.txt",
                {"email": confirmation.email_address.email},
            )
            return self.respond(False)

        # In the event someone clicks on an email confirmation link
        # for one account while logged into another account,
        # logout of the currently logged in account.
        if (
            self.request.user.is_authenticated
            and self.request.user.pk != confirmation.email_address.user_id
        ):
            self.logout()

        get_adapter(self.request).add_message(
            self.request,
            messages.SUCCESS,
            "account/messages/email_confirmed.txt",
            {"email": confirmation.email_address.email},
        )
        if app_settings.LOGIN_ON_EMAIL_CONFIRMATION:
            resp = self.login_on_confirm(confirmation)
            if resp is not None:
                return resp
        # Don't -- allauth doesn't touch is_active so that sys admin can
        # use it to block users et al
        #
        # user = confirmation.email_address.user
        # user.is_active = True
        # user.save()
        return self.respond(True)
0

1Answer

Your answer might help someone💌