Using htmx.org in a Django application is proving to be a very welcome way to handle AJAX calls without leaving Python. However, if a logged in user gets logged out for some reason, the calls to hx-post commands may seem to go unanswered. Digging through the response one would find the response indicates a bad CSRF token. Outlined here is one way to manage redirecting the browser to a message indicating that the session has been logged out. I wouldn't be surprised if there is a built in way to handle this with just htmx as I'm still in the early stages of using the htmx library.
For the purposes of this article, we've got an application called core which is already in INSTALLED_APPS.
We'll take advantage of a built in Django setting which can be set in settings.py. That setting is: CSRF_FAILURE_VIEW which we'll set to core.views.csrf_not_valid.
From the documentation:
Default: django.views.csrf.csrf_failure A dotted path to the view function to be used when an incoming request is rejected by the CSRF protection. The function should have this signature: def csrf_failure(request, reason=""): where reason is a short message (intended for developers or logging, not for end users) indicating the reason the request was rejected. It should return an HttpResponseForbidden.
django.views.csrf.csrf_failure() accepts an additional template_name parameter that defaults to '403_csrf.html'. If a template with that name exists, it will be used to render the page.
So we'll need a couple of views which will handle the routing.
from django.http import HttpResponse
from django.urls import reverse
def csrf_not_valid(request, reason=None, template_name=None):
""" specified in settings.py as the callable for when csrf is not valid """
response = HttpResponse('csrf in not valid')
response["HX-Redirect"] = reverse('core:logged_out')
return response
def logged_out(request):
# todo provide a clean logged out page.
return HttpResponse(" You've been logged out")
For logged_out you could render a proper page, or even in csrf_not_valid you could redirect to a login page instead of redirecting to the logged_out view. In any case the CSRF_FAILURE_VIEW makes it easy to catch all the hx-post calls in one easy spot.
Cover photo from Michael Jasmund.