{"title":"How to use Django’s CSRF protection","version":"5.0","locale":"en","docname":"howto/csrf","url":"/en/5.0/howto/csrf/","canonical":"https://djangodocs.dev/en/5.0/howto/csrf/","summary":"To take advantage of CSRF protection in your views, follow these steps: The CSRF middleware is activated by default in the MIDDLEWARE setting. If you override that…","html":"<span id=\"using-csrf\"></span><h1>How to use Django’s CSRF protection<a class=\"heading-anchor\" href=\"#how-to-use-django-s-csrf-protection\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>To take advantage of CSRF protection in your views, follow these steps:</p>\n<ol class=\"arabic\">\n<li><p>The CSRF middleware is activated by default in the <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>\nsetting. If you override that setting, remember that\n<code class=\"docutils literal notranslate\"><span class=\"pre\">'django.middleware.csrf.CsrfViewMiddleware'</span></code> should come before any view\nmiddleware that assume that CSRF attacks have been dealt with.</p>\n<p>If you disabled it, which is not recommended, you can use\n<a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_protect()</span></code></a> on particular views\nyou want to protect (see below).</p>\n</li>\n<li><p>In any template that uses a POST form, use the <a class=\"reference internal\" href=\"/en/5.0/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> tag inside\nthe <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> element if the form is for an internal URL, e.g.:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">&quot;post&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{%</span> <span class=\"k\">csrf_token</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>This should not be done for POST forms that target external URLs, since\nthat would cause the CSRF token to be leaked, leading to a vulnerability.</p>\n</li>\n<li><p>In the corresponding view functions, ensure that\n<a class=\"reference internal\" href=\"/en/5.0/ref/templates/api/#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RequestContext</span></code></a> is used to render the response so\nthat <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> will work properly. If you’re using the\n<a class=\"reference internal\" href=\"/en/5.0/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render()</span></code></a> function, generic views, or contrib apps,\nyou are covered already since these all use <code class=\"docutils literal notranslate\"><span class=\"pre\">RequestContext</span></code>.</p></li>\n</ol>\n<section id=\"using-csrf-protection-with-ajax\">\n<span id=\"csrf-ajax\"></span><h2>Using CSRF protection with AJAX<a class=\"heading-anchor\" href=\"#using-csrf-protection-with-ajax\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>While the above method can be used for AJAX POST requests, it has some\ninconveniences: you have to remember to pass the CSRF token in as POST data with\nevery POST request. For this reason, there is an alternative method: on each\nXMLHttpRequest, set a custom <code class=\"docutils literal notranslate\"><span class=\"pre\">X-CSRFToken</span></code> header (as specified by the\n<a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_HEADER_NAME\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_HEADER_NAME</span></code></a> setting) to the value of the CSRF token. This is\noften easier because many JavaScript frameworks provide hooks that allow\nheaders to be set on every request.</p>\n<p>First, you must get the CSRF token. How to do that depends on whether or not\nthe <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_USE_SESSIONS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_USE_SESSIONS</span></code></a> and <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_COOKIE_HTTPONLY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_HTTPONLY</span></code></a> settings\nare enabled.</p>\n<section id=\"acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false\">\n<span id=\"acquiring-csrf-token-from-cookie\"></span><h3>Acquiring the token if <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_USE_SESSIONS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_USE_SESSIONS</span></code></a> and <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_COOKIE_HTTPONLY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_HTTPONLY</span></code></a> are <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code><a class=\"heading-anchor\" href=\"#acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The recommended source for the token is the <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code> cookie, which will be\nset if you’ve enabled CSRF protection for your views as outlined above.</p>\n<p>The CSRF token cookie is named <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code> by default, but you can control\nthe cookie name via the <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_COOKIE_NAME\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_NAME</span></code></a> setting.</p>\n<p>You can acquire the token like this:</p>\n<div class=\"code-block\" data-language=\"javascript\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">JavaScript</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"JavaScript code\"><code><span class=\"kd\">function</span><span class=\"w\"> </span><span class=\"nx\">getCookie</span><span class=\"p\">(</span><span class=\"nx\">name</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">    </span><span class=\"kd\">let</span><span class=\"w\"> </span><span class=\"nx\">cookieValue</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"kc\">null</span><span class=\"p\">;</span>\n<span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"w\"> </span><span class=\"o\">&amp;&amp;</span><span class=\"w\"> </span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"w\"> </span><span class=\"o\">!==</span><span class=\"w\"> </span><span class=\"s1\">&#39;&#39;</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">        </span><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">cookies</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"p\">.</span><span class=\"nx\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;;&#39;</span><span class=\"p\">);</span>\n<span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"kd\">let</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"mf\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">cookies</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">            </span><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">cookie</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nx\">cookies</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">].</span><span class=\"nx\">trim</span><span class=\"p\">();</span>\n<span class=\"w\">            </span><span class=\"c1\">// Does this cookie string begin with the name we want?</span>\n<span class=\"w\">            </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">cookie</span><span class=\"p\">.</span><span class=\"nx\">substring</span><span class=\"p\">(</span><span class=\"mf\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">name</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"mf\">1</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">===</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">name</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"s1\">&#39;=&#39;</span><span class=\"p\">))</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">                </span><span class=\"nx\">cookieValue</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nb\">decodeURIComponent</span><span class=\"p\">(</span><span class=\"nx\">cookie</span><span class=\"p\">.</span><span class=\"nx\">substring</span><span class=\"p\">(</span><span class=\"nx\">name</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"mf\">1</span><span class=\"p\">));</span>\n<span class=\"w\">                </span><span class=\"k\">break</span><span class=\"p\">;</span>\n<span class=\"w\">            </span><span class=\"p\">}</span>\n<span class=\"w\">        </span><span class=\"p\">}</span>\n<span class=\"w\">    </span><span class=\"p\">}</span>\n<span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">cookieValue</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n<span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">csrftoken</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nx\">getCookie</span><span class=\"p\">(</span><span class=\"s1\">&#39;csrftoken&#39;</span><span class=\"p\">);</span>\n</code></pre></div>\n<p>The above code could be simplified by using the <a class=\"reference external\" href=\"https://github.com/js-cookie/js-cookie/\">JavaScript Cookie library</a> to replace <code class=\"docutils literal notranslate\"><span class=\"pre\">getCookie</span></code>:</p>\n<div class=\"code-block\" data-language=\"javascript\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">JavaScript</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"JavaScript code\"><code><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">csrftoken</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nx\">Cookies</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;csrftoken&#39;</span><span class=\"p\">);</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>The CSRF token is also present in the DOM in a masked form, but only if\nexplicitly included using <a class=\"reference internal\" href=\"/en/5.0/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> in a template. The cookie\ncontains the canonical, unmasked token. The\n<a class=\"reference internal\" href=\"/en/5.0/ref/middleware/#django.middleware.csrf.CsrfViewMiddleware\" title=\"django.middleware.csrf.CsrfViewMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code></a> will accept either.\nHowever, in order to protect against <a class=\"reference external\" href=\"https://www.breachattack.com/\">BREACH</a> attacks, it’s recommended to\nuse a masked token.</p>\n</aside>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>If your view is not rendering a template containing the <a class=\"reference internal\" href=\"/en/5.0/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a>\ntemplate tag, Django might not set the CSRF token cookie. This is common in\ncases where forms are dynamically added to the page. To address this case,\nDjango provides a view decorator which forces setting of the cookie:\n<a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.ensure_csrf_cookie\" title=\"django.views.decorators.csrf.ensure_csrf_cookie\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">ensure_csrf_cookie()</span></code></a>.</p>\n</aside>\n</section>\n<section id=\"acquiring-the-token-if-csrf-use-sessions-or-csrf-cookie-httponly-is-true\">\n<span id=\"acquiring-csrf-token-from-html\"></span><h3>Acquiring the token if <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_USE_SESSIONS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_USE_SESSIONS</span></code></a> or <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_COOKIE_HTTPONLY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_HTTPONLY</span></code></a> is <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code><a class=\"heading-anchor\" href=\"#acquiring-the-token-if-csrf-use-sessions-or-csrf-cookie-httponly-is-true\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If you activate <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_USE_SESSIONS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_USE_SESSIONS</span></code></a> or\n<a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_COOKIE_HTTPONLY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_HTTPONLY</span></code></a>, you must include the CSRF token in your HTML\nand read the token from the DOM with JavaScript:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">csrf_token</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">script</span><span class=\"p\">&gt;</span>\n<span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">csrftoken</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">querySelector</span><span class=\"p\">(</span><span class=\"s1\">&#39;[name=csrfmiddlewaretoken]&#39;</span><span class=\"p\">).</span><span class=\"nx\">value</span><span class=\"p\">;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">script</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"setting-the-token-on-the-ajax-request\">\n<h3>Setting the token on the AJAX request<a class=\"heading-anchor\" href=\"#setting-the-token-on-the-ajax-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Finally, you’ll need to set the header on your AJAX request. Using the\n<a class=\"reference external\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/fetch\">fetch()</a> API:</p>\n<div class=\"code-block\" data-language=\"javascript\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">JavaScript</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"JavaScript code\"><code><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">request</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"ow\">new</span><span class=\"w\"> </span><span class=\"nx\">Request</span><span class=\"p\">(</span>\n<span class=\"w\">    </span><span class=\"cm\">/* URL */</span><span class=\"p\">,</span>\n<span class=\"w\">    </span><span class=\"p\">{</span>\n<span class=\"w\">        </span><span class=\"nx\">method</span><span class=\"o\">:</span><span class=\"w\"> </span><span class=\"s1\">&#39;POST&#39;</span><span class=\"p\">,</span>\n<span class=\"w\">        </span><span class=\"nx\">headers</span><span class=\"o\">:</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"s1\">&#39;X-CSRFToken&#39;</span><span class=\"o\">:</span><span class=\"w\"> </span><span class=\"nx\">csrftoken</span><span class=\"p\">},</span>\n<span class=\"w\">        </span><span class=\"nx\">mode</span><span class=\"o\">:</span><span class=\"w\"> </span><span class=\"s1\">&#39;same-origin&#39;</span><span class=\"w\"> </span><span class=\"c1\">// Do not send CSRF token to another domain.</span>\n<span class=\"w\">    </span><span class=\"p\">}</span>\n<span class=\"p\">);</span>\n<span class=\"nx\">fetch</span><span class=\"p\">(</span><span class=\"nx\">request</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">response</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">    </span><span class=\"c1\">// ...</span>\n<span class=\"p\">});</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"using-csrf-protection-in-jinja2-templates\">\n<h2>Using CSRF protection in Jinja2 templates<a class=\"heading-anchor\" href=\"#using-csrf-protection-in-jinja2-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django’s <a class=\"reference internal\" href=\"/en/5.0/topics/templates/#django.template.backends.jinja2.Jinja2\" title=\"django.template.backends.jinja2.Jinja2\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Jinja2</span></code></a> template backend\nadds <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">csrf_input</span> <span class=\"pre\">}}</span></code> to the context of all templates which is equivalent\nto <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> in the Django template language. For example:</p>\n<div class=\"code-block\" data-language=\"html+jinja\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Html Jinja</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Html Jinja code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">&quot;post&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">csrf_input</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n</section>\n<section id=\"using-the-decorator-method\">\n<h2>Using the decorator method<a class=\"heading-anchor\" href=\"#using-the-decorator-method\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Rather than adding <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> as a blanket protection, you can use\nthe <a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_protect()</span></code></a> decorator, which has\nexactly the same functionality, on particular views that need the protection.\nIt must be used <strong>both</strong> on views that insert the CSRF token in the output, and\non those that accept the POST form data. (These are often the same view\nfunction, but not always).</p>\n<p>Use of the decorator by itself is <strong>not recommended</strong>, since if you forget to\nuse it, you will have a security hole. The ‘belt and braces’ strategy of using\nboth is fine, and will incur minimal overhead.</p>\n</section>\n<section id=\"handling-rejected-requests\">\n<span id=\"csrf-rejected-requests\"></span><h2>Handling rejected requests<a class=\"heading-anchor\" href=\"#handling-rejected-requests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>By default, a ‘403 Forbidden’ response is sent to the user if an incoming\nrequest fails the checks performed by <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>. This should\nusually only be seen when there is a genuine Cross Site Request Forgery, or\nwhen, due to a programming error, the CSRF token has not been included with a\nPOST form.</p>\n<p>The error page, however, is not very friendly, so you may want to provide your\nown view for handling this condition. To do this, set the\n<a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-CSRF_FAILURE_VIEW\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_FAILURE_VIEW</span></code></a> setting.</p>\n<p>CSRF failures are logged as warnings to the <a class=\"reference internal\" href=\"/en/5.0/ref/logging/#django-security-logger\"><span class=\"std std-ref\">django.security.csrf</span></a> logger.</p>\n</section>\n<section id=\"using-csrf-protection-with-caching\">\n<h2>Using CSRF protection with caching<a class=\"heading-anchor\" href=\"#using-csrf-protection-with-caching\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>If the <a class=\"reference internal\" href=\"/en/5.0/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> template tag is used by a template (or the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">get_token</span></code> function is called some other way), <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> will\nadd a cookie and a <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary:</span> <span class=\"pre\">Cookie</span></code> header to the response. This means that the\nmiddleware will play well with the cache middleware if it is used as instructed\n(<code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> goes before all other middleware).</p>\n<p>However, if you use cache decorators on individual views, the CSRF middleware\nwill not yet have been able to set the Vary header or the CSRF cookie, and the\nresponse will be cached without either one. In this case, on any views that\nwill require a CSRF token to be inserted you should use the\n<a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.views.decorators.csrf.csrf_protect()</span></code></a> decorator first:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache_page</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.csrf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">csrf_protect</span>\n\n\n<span class=\"nd\">@cache_page</span><span class=\"p\">(</span><span class=\"mi\">60</span> <span class=\"o\">*</span> <span class=\"mi\">15</span><span class=\"p\">)</span>\n<span class=\"nd\">@csrf_protect</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>If you are using class-based views, you can refer to <a class=\"reference internal\" href=\"/en/5.0/topics/class-based-views/intro/#id1\"><span class=\"std std-ref\">Decorating\nclass-based views</span></a>.</p>\n</section>\n<section id=\"testing-and-csrf-protection\">\n<h2>Testing and CSRF protection<a class=\"heading-anchor\" href=\"#testing-and-csrf-protection\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> will usually be a big hindrance to testing view\nfunctions, due to the need for the CSRF token which must be sent with every POST\nrequest. For this reason, Django’s HTTP client for tests has been modified to\nset a flag on requests which relaxes the middleware and the <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code>\ndecorator so that they no longer rejects requests. In every other respect\n(e.g. sending cookies etc.), they behave the same.</p>\n<p>If, for some reason, you <em>want</em> the test client to perform CSRF\nchecks, you can create an instance of the test client that enforces\nCSRF checks:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Client</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">csrf_client</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">(</span><span class=\"n\">enforce_csrf_checks</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"edge-cases\">\n<h2>Edge cases<a class=\"heading-anchor\" href=\"#edge-cases\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Certain views can have unusual requirements that mean they don’t fit the normal\npattern envisaged here. A number of utilities can be useful in these\nsituations. The scenarios they might be needed in are described in the following\nsection.</p>\n<section id=\"disabling-csrf-protection-for-just-a-few-views\">\n<h3>Disabling CSRF protection for just a few views<a class=\"heading-anchor\" href=\"#disabling-csrf-protection-for-just-a-few-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Most views requires CSRF protection, but a few do not.</p>\n<p>Solution: rather than disabling the middleware and applying <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> to\nall the views that need it, enable the middleware and use\n<a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a>.</p>\n</section>\n<section id=\"setting-the-token-when-csrfviewmiddleware-process-view-is-not-used\">\n<h3>Setting the token when <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view()</span></code> is not used<a class=\"heading-anchor\" href=\"#setting-the-token-when-csrfviewmiddleware-process-view-is-not-used\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>There are cases when <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view</span></code> may not have run\nbefore your view is run - 404 and 500 handlers, for example - but you still\nneed the CSRF token in a form.</p>\n<p>Solution: use <a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.requires_csrf_token\" title=\"django.views.decorators.csrf.requires_csrf_token\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">requires_csrf_token()</span></code></a></p>\n</section>\n<section id=\"including-the-csrf-token-in-an-unprotected-view\">\n<h3>Including the CSRF token in an unprotected view<a class=\"heading-anchor\" href=\"#including-the-csrf-token-in-an-unprotected-view\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>There may be some views that are unprotected and have been exempted by\n<code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_exempt</span></code>, but still need to include the CSRF token.</p>\n<p>Solution: use <a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a> followed by\n<a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.requires_csrf_token\" title=\"django.views.decorators.csrf.requires_csrf_token\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">requires_csrf_token()</span></code></a>. (i.e. <code class=\"docutils literal notranslate\"><span class=\"pre\">requires_csrf_token</span></code>\nshould be the innermost decorator).</p>\n</section>\n<section id=\"protecting-a-view-for-only-one-path\">\n<h3>Protecting a view for only one path<a class=\"heading-anchor\" href=\"#protecting-a-view-for-only-one-path\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A view needs CSRF protection under one set of conditions only, and mustn’t have\nit for the rest of the time.</p>\n<p>Solution: use <a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a> for the whole\nview function, and <a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_protect()</span></code></a> for the\npath within it that needs protection. Example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.csrf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">csrf_exempt</span><span class=\"p\">,</span> <span class=\"n\">csrf_protect</span>\n\n\n<span class=\"nd\">@csrf_exempt</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"nd\">@csrf_protect</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">protected_path</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n        <span class=\"n\">do_something</span><span class=\"p\">()</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">some_condition</span><span class=\"p\">():</span>\n        <span class=\"k\">return</span> <span class=\"n\">protected_path</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">do_something_else</span><span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"protecting-a-page-that-uses-ajax-without-an-html-form\">\n<h3>Protecting a page that uses AJAX without an HTML form<a class=\"heading-anchor\" href=\"#protecting-a-page-that-uses-ajax-without-an-html-form\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A page makes a POST request via AJAX, and the page does not have an HTML form\nwith a <a class=\"reference internal\" href=\"/en/5.0/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> that would cause the required CSRF cookie to be sent.</p>\n<p>Solution: use <a class=\"reference internal\" href=\"/en/5.0/ref/csrf/#django.views.decorators.csrf.ensure_csrf_cookie\" title=\"django.views.decorators.csrf.ensure_csrf_cookie\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">ensure_csrf_cookie()</span></code></a> on the\nview that sends the page.</p>\n</section>\n</section>\n<section id=\"csrf-protection-in-reusable-applications\">\n<h2>CSRF protection in reusable applications<a class=\"heading-anchor\" href=\"#csrf-protection-in-reusable-applications\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Because it is possible for the developer to turn off the <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>,\nall relevant views in contrib apps use the <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> decorator to ensure\nthe security of these applications against CSRF. It is recommended that the\ndevelopers of other reusable apps that want the same guarantees also use the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> decorator on their views.</p>\n</section>","rootId":"how-to-use-django-s-csrf-protection","toc":[{"title":"Using CSRF protection with AJAX","anchor":"using-csrf-protection-with-ajax","children":[{"title":"Acquiring the token if CSRF_USE_SESSIONS and CSRF_COOKIE_HTTPONLY are False","anchor":"acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false","children":[]},{"title":"Acquiring the token if CSRF_USE_SESSIONS or CSRF_COOKIE_HTTPONLY is True","anchor":"acquiring-the-token-if-csrf-use-sessions-or-csrf-cookie-httponly-is-true","children":[]},{"title":"Setting the token on the AJAX request","anchor":"setting-the-token-on-the-ajax-request","children":[]}]},{"title":"Using CSRF protection in Jinja2 templates","anchor":"using-csrf-protection-in-jinja2-templates","children":[]},{"title":"Using the decorator method","anchor":"using-the-decorator-method","children":[]},{"title":"Handling rejected requests","anchor":"handling-rejected-requests","children":[]},{"title":"Using CSRF protection with caching","anchor":"using-csrf-protection-with-caching","children":[]},{"title":"Testing and CSRF protection","anchor":"testing-and-csrf-protection","children":[]},{"title":"Edge cases","anchor":"edge-cases","children":[{"title":"Disabling CSRF protection for just a few views","anchor":"disabling-csrf-protection-for-just-a-few-views","children":[]},{"title":"Setting the token when CsrfViewMiddleware.process_view() is not used","anchor":"setting-the-token-when-csrfviewmiddleware-process-view-is-not-used","children":[]},{"title":"Including the CSRF token in an unprotected view","anchor":"including-the-csrf-token-in-an-unprotected-view","children":[]},{"title":"Protecting a view for only one path","anchor":"protecting-a-view-for-only-one-path","children":[]},{"title":"Protecting a page that uses AJAX without an HTML form","anchor":"protecting-a-page-that-uses-ajax-without-an-html-form","children":[]}]},{"title":"CSRF protection in reusable applications","anchor":"csrf-protection-in-reusable-applications","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"“How-to” guides","url":"/en/5.0/howto/"}],"prev":{"docname":"howto/auth-remote-user","title":"How to authenticate using REMOTE_USER","url":"/en/5.0/howto/auth-remote-user/"},"next":{"docname":"howto/custom-management-commands","title":"How to create custom django-admin commands","url":"/en/5.0/howto/custom-management-commands/"},"formats":{"html":"/en/5.0/howto/csrf/","markdown":"/en/5.0/howto/csrf.md","json":"/en/5.0/howto/csrf.json"},"source":"https://github.com/django/django/blob/stable/5.0.x/docs/howto/csrf.txt","official":"https://docs.djangoproject.com/en/5.0/howto/csrf/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}