[Solved]-Django does not send csrf token again after browser cookies has been cleared



Look at django/middleware/csrf.py in which CsrfViewMiddleware class is declared. As you can see in def process_response(self, request, response) there are three conditions that prevent cookie setup:

def process_response(self, request, response):
    if getattr(response, 'csrf_processing_done', False):
        return response

    # If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was
    # never called, probaby because a request middleware returned a response
    # (for example, contrib.auth redirecting to a login page).
    if request.META.get("CSRF_COOKIE") is None:
        return response

    if not request.META.get("CSRF_COOKIE_USED", False):
        return response

    # Set the CSRF cookie even if it's already set, so we renew
    # the expiry timer.
                        max_age = 60 * 60 * 24 * 7 * 52,
    # Content varies with the CSRF cookie, so set the Vary header.
    patch_vary_headers(response, ('Cookie',))
    response.csrf_processing_done = True
    return response

Check which is applied for you.

๐Ÿ‘คPavel Reznikov


I had the same problem. After debugging against django source, the reason is:

If your view is not rendering a template containing the csrf_token
template tag, Django might not set the CSRF token cookie.

Two solutions:

  • Add {% csrf_token %} in your template
  • Use @ensure_csrf_cookie decorator for your view

For detail your can refer django doc.

๐Ÿ‘คHan He


In my case, the problem was VSCode debugger.
I turned on server via VSCode debug mode, then open new incognito window (obviously there were no cookies), and django stopped setting missing cookie.
When I started server as normal, the problem has gone.



In most cases issue caused by second check mentioned in a previous answer

if not request.META.get("CSRF_COOKIE_USED", False):
        return response

This can be solved by using @ensure_csrf_cookie decorator for the view. If used โ€“ check is passed and cookie is set/renewed each time view is rendered.

See also related topic: Using ajax request in Django without form element


Leave a comment