Search code examples
djangodjango-rest-frameworkdjango-allauthdjango-rest-auth

django-rest-auth handling expired confirmation email


I am using django-rest-auth and django-allauth to handle user authentication in my rest api. When a user tries to verify their email after the link has expired, I get an unpleasant error page.

enter image description here

Please, how can I display a better error page or send a message telling them it wasn't successful because the link had expired?


Solution

  • As far as I can understand, your error is coming from django-allauth, not from your project. Reason for the error is that you did not include allauth.url in your main urls.py(will explain more in later section).

    Possible solutions

    First Solution

    Add allauth.urls in your urls.py:

    urlpatterns = [
        ...
        path('accounts/', include('allauth.urls')),
        ...
    ]
    

    Second Solution

    If you go deep into the problem, you will see the error is saying NoReverseMatch error, which occurs when there is a url name which is not found in project ie account_login. Now this error is coming from template at at allauth base template.

    Judging by your code, this error is occurring due to these line: (I took the liberty to check your github codebase as it was opensource.)

    if not email_confirmation:
        if queryset is None:
            queryset = self.get_queryset()
        try:
            email_confirmation = queryset.get(key=key.lower())
        except EmailConfirmation.DoesNotExist:
            # A React/Vue Router Route will handle the failure scenario
            return HttpResponseRedirect('/login/failure/')  # <-- Here
    

    It is pointing to a wrong url which does not exist in system. Please check django-rest-auth urls.

    So one fix here is to provide a template response here with a view like this:

    # in accounts/api/urls.py
    path('failure/', TemplateView.as_view(template_name='api_failure.html'))
    

    Another solution is to provide custom 404 template like this:

    # accounts/api/views.py
    def handler404(request, exception, template_name="your_custom_404.html"):
        response = render_to_response(template_name)
        response.status_code = 404
        return response
    
    # root urls.py
    
     handler404 = 'accounts.api.views.handler404'