{"title":"Comment utiliser la protection CSRF de Django","version":"6.1","locale":"fr","docname":"howto/csrf","url":"/fr/6.1/howto/csrf/","canonical":"https://djangodocs.dev/fr/6.1/howto/csrf/","summary":"Pour profiter de la protection CSRF dans les vues, procédez comme suit : The CSRF middleware is activated by default in the MIDDLEWARE setting. If you override that…","html":"<span id=\"using-csrf\"></span><h1>Comment utiliser la protection CSRF de Django<a class=\"heading-anchor\" href=\"#how-to-use-django-s-csrf-protection\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Pour profiter de la protection CSRF dans les vues, procédez comme suit :</p>\n<ol class=\"arabic\">\n<li><p>The CSRF middleware is activated by default in the <a class=\"reference internal\" href=\"/fr/6.1/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 assumes that CSRF attacks have been dealt with.</p>\n<p>Si vous le désactivez, ce qui n’est pas recommandé, vous pouvez utiliser <a class=\"reference internal\" href=\"/fr/6.1/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> sur certaines vues que vous souhaitez protéger (voir ci-dessous).</p>\n</li>\n<li><p>Dans tout gabarit qui utilise un formulaire POST, utilisez la balise de gabarit <a class=\"reference internal\" href=\"/fr/6.1/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> à l’intérieur de la balise HTML <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> si le formulaire renvoie vers une URL interne, par exemple :</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>Par contre, il ne faut pas le faire pour les formulaires POST qui ciblent des URL externes, car cela entraînerait la divulgation du jeton CSRF, et conduirait ainsi à une vulnérabilité.</p>\n</li>\n<li><p>Dans les fonctions de vue correspondantes, vérifiez que <a class=\"reference internal\" href=\"/fr/6.1/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> est utilisé pour produire la réponse afin que <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> fonctionne correctement. Si vous utilisez la fonction <a class=\"reference internal\" href=\"/fr/6.1/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>, les vues génériques ou les applications contribuées, il n’y a pas de soucis à se faire car toutes ces vues utilisent <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>Utilisation de la protection CSRF avec AJAX<a class=\"heading-anchor\" href=\"#using-csrf-protection-with-ajax\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Même si la méthode ci-dessus peut être utilisée pour les requêtes AJAX POST, elle présente quelques inconvénients : il ne faut pas oublier de passer le jeton CSRF en même temps que les données POST à ​​chaque requête POST. Pour cette raison, il y a une autre méthode : sur chaque XMLHttpRequest, définissez un élément d’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">X-CSRFToken</span></code> (tel qu’indiqué par le réglage <a class=\"reference internal\" href=\"/fr/6.1/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>) ayant la même valeur que le jeton CSRF. C’est souvent plus simple, parce que de nombreuses bibliothèques JavaScript fournissent des points d’extension qui permettent d’ajouter des éléments d’en-tête pour chaque requête.</p>\n<p>Il faut d’abord obtenir le jeton CSRF. La façon de faire dépend de l’activation ou non des réglages <a class=\"reference internal\" href=\"/fr/6.1/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> et <a class=\"reference internal\" href=\"/fr/6.1/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>.</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>Acquisition du jeton si <a class=\"reference internal\" href=\"/fr/6.1/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> et <a class=\"reference internal\" href=\"/fr/6.1/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> valent <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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La source recommandée pour le jeton est le cookie <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code>, qui sera présent si vous avez activé la protection CSRF pour votre vue, comme indiqué ci-dessus.</p>\n<p>Le cookie CSRF est nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code> par défaut, mais vous pouvez modifier ce nom via le réglage <a class=\"reference internal\" href=\"/fr/6.1/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>.</p>\n<p>Vous pouvez obtenir le jeton comme ceci :</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>Le code ci-dessus pourrait être simplifié en utilisant la <a class=\"reference external\" href=\"https://github.com/js-cookie/js-cookie/\">bibliothèque JavaScript Cookie</a> pour remplacer <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>Le jeton CSRF est aussi présent dans le DOM sous une forme masquée, mais seulement dans le cas où il est explicitement ajouté avec <a class=\"reference internal\" href=\"/fr/6.1/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> dans un gabarit. Le cookie contient le jeton sous sa forme canonique, non masquée.  <a class=\"reference internal\" href=\"/fr/6.1/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> accepte les deux formes. Cependant, afin de vous protéger contre les attaques de type <a class=\"reference external\" href=\"https://www.breachattack.com/\">BREACH</a>, il est recommandé d’utiliser le jeton masqué.</p>\n</aside>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Si la vue n’utilise pas un gabarit contenant la balise <a class=\"reference internal\" href=\"/fr/6.1/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a>, Django peut ne pas définir le cookie CSRF. Cette situation apparaît souvent dans les cas où les formulaires sont ajoutés dynamiquement à la page. Pour résoudre ce problème, Django fournit un décorateur de vue qui force l’utilisation du cookie : <a class=\"reference internal\" href=\"/fr/6.1/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>Acquisition du jeton si <a class=\"reference internal\" href=\"/fr/6.1/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> ou <a class=\"reference internal\" href=\"/fr/6.1/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> vaut <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\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous activez <a class=\"reference internal\" href=\"/fr/6.1/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> ou <a class=\"reference internal\" href=\"/fr/6.1/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>, vous devez inclure le jeton CSRF dans le code HTML et lire le jeton dans le DOM en 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>Définition du jeton pour une requête AJAX<a class=\"heading-anchor\" href=\"#setting-the-token-on-the-ajax-request\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Enfin, vous devrez renseigner l’en-tête de votre requête AJAX. En utilisant l’API <a class=\"reference external\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/fetch\">fetch()</a> :</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>Utilisation de la protection CSRF dans les gabarits Jinja2<a class=\"heading-anchor\" href=\"#using-csrf-protection-in-jinja2-templates\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Le moteur de gabarit <a class=\"reference internal\" href=\"/fr/6.1/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> de Django ajoute <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">csrf_input</span> <span class=\"pre\">}}</span></code> au contexte de tous les gabarits, ce qui est équivalent à <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> dans le langage de gabarit de Django. Par exemple :</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>La méthode du décorateur<a class=\"heading-anchor\" href=\"#using-the-decorator-method\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Plutôt que d’ajouter <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> comme une protection générale, vous pouvez utiliser le décorateur <a class=\"reference internal\" href=\"/fr/6.1/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>, qui offre exactement la même fonctionnalité, sur les vues particulières qui ont besoin de la protection. Ce décorateur doit être utilisé <strong>à la fois</strong> sur les vues qui insèrent le jeton CSRF dans leur rendu, et sur celles qui acceptent les données de formulaire POST (il s’agit souvent de la même fonction de vue, mais pas toujours).</p>\n<p>Le recours à l’utilisation seule du décorateur <strong>n’est pas recommandé</strong>, car si vous oubliez de l’utiliser, vous aurez un trou de sécurité. La stratégie « ceinture et bretelles » qui consiste à utiliser les deux convient tout à fait et n’entraînera qu’une surcharge minimale.</p>\n</section>\n<section id=\"handling-rejected-requests\">\n<span id=\"csrf-rejected-requests\"></span><h2>Gestion des requêtes rejetées<a class=\"heading-anchor\" href=\"#handling-rejected-requests\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Par défaut, une réponse de type « 403 Forbidden » est renvoyée à l’utilisateur si une requête entrante ne satisfait pas les contrôles effectués par <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>. Ça ne devrait généralement apparaître que lorsqu’il s’agit d’une véritable attaque de type « Cross Site Request Forgery », ou lorsqu’en raison d’une erreur de programmation, le jeton CSRF n’a pas été inclus dans un formulaire de type POST.</p>\n<p>La page d’erreur n’est toutefois pas très sympathique, de sorte que vous pouvez fournir votre propre vue pour traiter cette condition. Pour ce faire, définissez le réglage <a class=\"reference internal\" href=\"/fr/6.1/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>.</p>\n<p>Les échecs CSRF sont journalisés comme avertissements dans le journaliseur <a class=\"reference internal\" href=\"/fr/6.1/ref/logging/#django-security-logger\"><span class=\"std std-ref\">django.security.csrf</span></a>.</p>\n</section>\n<section id=\"using-csrf-protection-with-caching\">\n<span id=\"csrf-cache-page\"></span><h2>Utilisation de la protection CSRF avec le cache<a class=\"heading-anchor\" href=\"#using-csrf-protection-with-caching\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si la balise de gabarit <a class=\"reference internal\" href=\"/fr/6.1/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> est utilisée par un gabarit (ou que la fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">get_token</span></code> est appelée d’une autre façon), l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> ajoute un cookie et un en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary:</span> <span class=\"pre\">Cookie</span></code> à la réponse. Cela signifie que l’intergiciel fonctionnera bien avec l’intergiciel de cache s’il est utilisé conformément aux instructions (<code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> doit être placé dans les réglages avant tout autre intergiciel).</p>\n<p>Toutefois, si vous utilisez des décorateurs de cache sur des vues individuelles, l’intergiciel CSRF n’aura pas encore pu définir l’en-tête Vary ou le cookie CSRF, et la réponse sera mise en cache sans l’un ni l’autre. Dans ce cas, sur les vues qui nécessitent qu’un jeton CSRF soit inséré, vous devez utiliser le décorateur de fonction <a class=\"reference internal\" href=\"/fr/6.1/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> en premier :</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>Si vous utilisez des vues fondées sur les classes, vous pouvez vous référer à la <a class=\"reference internal\" href=\"/fr/6.1/topics/class-based-views/intro/#id1\"><span class=\"std std-ref\">Décoration des vues fondées sur les classes</span></a>.</p>\n</section>\n<section id=\"testing-and-csrf-protection\">\n<h2>La protection CSRF dans les tests<a class=\"heading-anchor\" href=\"#testing-and-csrf-protection\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Généralement, <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> gêne les tests des fonctions de vues, parce que le jeton CSRF doit être envoyé avec chaque requête POST. Le client HTTP de Django utilisé pour les tests a donc été modifié afin de marquer automatiquement les requêtes et ainsi d’informer l’intergiciel et le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> de manière à ce qu’ils ne rejettent pas ces requêtes. À tous les autres égards (par exemple, l’envoi des cookies, etc.), le comportement durant les tests est identique.</p>\n<p>Si pour une raison quelconque vous <em>voulez</em> que le client HTTP utilisé pour les tests effectue des contrôles CSRF, vous pouvez créer une instance du client de test qui applique les vérifications CSRF :</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>Cas particuliers<a class=\"heading-anchor\" href=\"#edge-cases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Certaines vues peuvent avoir des exigences inhabituelles qui impliquent qu’elles ne correspondent pas au modèle normal envisagé ici. Un certain nombre d’utilitaires peuvent être utiles dans ces situations. Les scénarios qui pourraient alors être nécessaires sont décrits dans la section suivante.</p>\n<section id=\"disabling-csrf-protection-for-just-a-few-views\">\n<h3>Désactivation de la protection CSRF pour quelques vues choisies<a class=\"heading-anchor\" href=\"#disabling-csrf-protection-for-just-a-few-views\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La plupart des vues nécessitent une protection CSRF, mais quelques-unes n’en ont pas besoin.</p>\n<p>Solution : plutôt que de désactiver l’intergiciel et d’appliquer <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> à toutes les vues qui en ont besoin, activez l’intergiciel et utilisez <a class=\"reference internal\" href=\"/fr/6.1/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>Définition du jeton lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view()</span></code> n’est pas utilisée<a class=\"heading-anchor\" href=\"#setting-the-token-when-csrfviewmiddleware-process-view-is-not-used\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il y a des cas où <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view</span></code> n’aura pas été exécuté avant votre vue - les gestionnaires d’erreurs 404 et 500, par exemple - mais vous avez quand même besoin du jeton CSRF dans un formulaire.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"/fr/6.1/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>Inclusion du jeton CSRF dans une vue non protégée<a class=\"heading-anchor\" href=\"#including-the-csrf-token-in-an-unprotected-view\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Certaines vues peuvent ne pas être protégées, peut-être exemptées par <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_exempt</span></code>, mais ont tout de même besoin d’inclure le jeton CSRF.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"/fr/6.1/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> suivi de <a class=\"reference internal\" href=\"/fr/6.1/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> (c’est à dire que <code class=\"docutils literal notranslate\"><span class=\"pre\">requires_csrf_token</span></code> doit être le décorateur le plus à l’intérieur).</p>\n</section>\n<section id=\"protecting-a-view-for-only-one-path\">\n<h3>Protection d’une vue pour un seul chemin<a class=\"heading-anchor\" href=\"#protecting-a-view-for-only-one-path\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Une vue a besoin de protection CSRF seulement quand un certain nombre de conditions sont remplies, et ne doit pas être protégée le reste du temps.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"/fr/6.1/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> pour l’ensemble de la fonction de vue, et <a class=\"reference internal\" href=\"/fr/6.1/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> spécifiquement pour le chemin qui doit être protégé. Exemple :</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>Protection d’une page utilisant AJAX sans formulaire HTML<a class=\"heading-anchor\" href=\"#protecting-a-page-that-uses-ajax-without-an-html-form\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Une page effectue une requête POST via AJAX, et cette page n’a pas de formulaire HTML avec une balise <a class=\"reference internal\" href=\"/fr/6.1/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> qui provoquerait la transmission du cookie CSRF.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"/fr/6.1/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> sur la vue qui envoie la page.</p>\n</section>\n</section>\n<section id=\"csrf-protection-in-reusable-applications\">\n<h2>La protection CSRF dans les applications réutilisables<a class=\"heading-anchor\" href=\"#csrf-protection-in-reusable-applications\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Comme il est possible pour le développeur de désactiver l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>, toutes les vues concernées dans les applications « contrib » de Django utilisent le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> pour garantir la protection de ces applications contre les attaques CSRF. Il est recommandé que les développeurs d’autres applications réutilisables qui souhaitent offrir les mêmes garanties utilisent également le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> sur leurs vues.</p>\n</section>","rootId":"how-to-use-django-s-csrf-protection","toc":[{"title":"Utilisation de la protection CSRF avec AJAX","anchor":"using-csrf-protection-with-ajax","children":[{"title":"Acquisition du jeton si CSRF_USE_SESSIONS et CSRF_COOKIE_HTTPONLY valent False","anchor":"acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false","children":[]},{"title":"Acquisition du jeton si CSRF_USE_SESSIONS ou CSRF_COOKIE_HTTPONLY vaut True","anchor":"acquiring-the-token-if-csrf-use-sessions-or-csrf-cookie-httponly-is-true","children":[]},{"title":"Définition du jeton pour une requête AJAX","anchor":"setting-the-token-on-the-ajax-request","children":[]}]},{"title":"Utilisation de la protection CSRF dans les gabarits Jinja2","anchor":"using-csrf-protection-in-jinja2-templates","children":[]},{"title":"La méthode du décorateur","anchor":"using-the-decorator-method","children":[]},{"title":"Gestion des requêtes rejetées","anchor":"handling-rejected-requests","children":[]},{"title":"Utilisation de la protection CSRF avec le cache","anchor":"using-csrf-protection-with-caching","children":[]},{"title":"La protection CSRF dans les tests","anchor":"testing-and-csrf-protection","children":[]},{"title":"Cas particuliers","anchor":"edge-cases","children":[{"title":"Désactivation de la protection CSRF pour quelques vues choisies","anchor":"disabling-csrf-protection-for-just-a-few-views","children":[]},{"title":"Définition du jeton lorsque CsrfViewMiddleware.process_view() n’est pas utilisée","anchor":"setting-the-token-when-csrfviewmiddleware-process-view-is-not-used","children":[]},{"title":"Inclusion du jeton CSRF dans une vue non protégée","anchor":"including-the-csrf-token-in-an-unprotected-view","children":[]},{"title":"Protection d’une vue pour un seul chemin","anchor":"protecting-a-view-for-only-one-path","children":[]},{"title":"Protection d’une page utilisant AJAX sans formulaire HTML","anchor":"protecting-a-page-that-uses-ajax-without-an-html-form","children":[]}]},{"title":"La protection CSRF dans les applications réutilisables","anchor":"csrf-protection-in-reusable-applications","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Guides pratiques","url":"/fr/6.1/howto/"}],"prev":{"docname":"howto/csp","title":"Comment utiliser la politique de sécurité de contenu de Django","url":"/fr/6.1/howto/csp/"},"next":{"docname":"howto/custom-file-storage","title":"Écriture d’une classe de stockage personnalisée","url":"/fr/6.1/howto/custom-file-storage/"},"formats":{"html":"/fr/6.1/howto/csrf/","markdown":"/fr/6.1/howto/csrf.md","json":"/fr/6.1/howto/csrf.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/howto/csrf.txt","official":"https://docs.djangoproject.com/fr/6.1/howto/csrf/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}