{"title":"Django の CSRF 保護を利用する","version":"6.1","locale":"ja","docname":"howto/csrf","url":"/ja/6.1/howto/csrf/","canonical":"https://djangodocs.dev/ja/6.1/howto/csrf/","summary":"CSRF 対策をあなたのビューで有効にするには、以下の手順に従ってください: The CSRF middleware is activated by default in the MIDDLEWARE setting. If you override that setting, remember that…","html":"<span id=\"using-csrf\"></span><h1>Django の CSRF 保護を利用する<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>CSRF 対策をあなたのビューで有効にするには、以下の手順に従ってください:</p>\n<ol class=\"arabic\">\n<li><p>The CSRF middleware is activated by default in the <a class=\"reference internal\" href=\"/ja/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>(推奨されませんが) もし対策を無効にする場合は、<a class=\"reference internal\" href=\"/ja/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> を使って特定のビューを保護することができます (下記を参照してください)。</p>\n</li>\n<li><p>POST フォームを使う全てのテンプレートで、POST が内部 URL に使われる場合は、<code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> 要素の内部で <a class=\"reference internal\" href=\"/ja/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> タグを使用してください。</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>この方法は、外部の URL を対象にする POST フォームで使ってはいけません。CSRF トークンが外部に漏れ、脆弱性の原因となります。</p>\n</li>\n<li><p>対応するビュー関数では、<code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> が正しく機能するように、レスポンスをレンダリングする際に <a class=\"reference internal\" href=\"/ja/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> が使用されていることを確認してください。 <a class=\"reference internal\" href=\"/ja/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> 関数、ジェネリックビュー、または contrib アプリを使用している場合は、これらはすべて <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>AJAXでCSRF保護を利用する<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>上記の方法は AJAX の POST でも利用可能ですが、多少不便です。すべての POST リクエストで、CSRF トークンを POST するデータに忘れずに含めなければなりません。そのため、別の方法が用意されており、各 XMLHttpRequest に対して、<code class=\"docutils literal notranslate\"><span class=\"pre\">X-CSRFToken</span></code> という独自ヘッダーに CSRF トークンの値を設定することができます (<a class=\"reference internal\" href=\"/ja/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> 設定でヘッダー名が指定できます)。多くの JavaScript のフレームワークはすべてのリクエストについて、指定したヘッダーを設定するようなフック機能を提供しているので、普通は簡単に設定できます。</p>\n<p>まず、CSRFトークンを取得する必要があります。これは、<a class=\"reference internal\" href=\"/ja/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> と <a class=\"reference internal\" href=\"/ja/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><a class=\"reference internal\" href=\"/ja/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> と <a class=\"reference internal\" href=\"/ja/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> が <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>トークン取得のソースとして推奨されるのは <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code> クッキーです。これは、上記で概説したようにビューに対する CSRF 保護を有効化した場合にセットされます。</p>\n<p>デフォルトでは、CSRF トークンの cookie は <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code> という名前ですが、<a class=\"reference internal\" href=\"/ja/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>以下のようにしてトークンを取得できます:</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>上記のコードは <a class=\"reference external\" href=\"https://github.com/js-cookie/js-cookie/\">JavaScript Cookie library</a> を使って <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\">注釈</p>\n<p>CSRF トークンはマスクされた形で DOM にも存在しますが、これはテンプレート内で <a class=\"reference internal\" href=\"/ja/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> を使って明示的にインクルードされたときだけです。クッキーはマスクされていない正規のトークンを含んでいます。 <a class=\"reference internal\" href=\"/ja/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> はどちらも受け付けます。しかし、 <a class=\"reference external\" href=\"https://www.breachattack.com/\">BREACH</a> 攻撃から守るためには、マスクされたトークンを使うことを推奨します。</p>\n</aside>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>ビューが <a class=\"reference internal\" href=\"/ja/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 は CSRF トークンクッキーをセットしない可能性があります。フォームがページに動的に追加される場合がその典型です。このケースに対応するため、Django はクッキーを強制的にセットするビューのデコレータを提供しています: <a class=\"reference internal\" href=\"/ja/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><a class=\"reference internal\" href=\"/ja/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> または <a class=\"reference internal\" href=\"/ja/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> が <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><a class=\"reference internal\" href=\"/ja/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> または <a class=\"reference internal\" href=\"/ja/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> を有効にした場合、HTML に CSRF トークンを含め、JavaScript で DOM からトークンを読み取る必要があります:</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>AJAX 通信でトークンを設定する<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>最後に、AJAXリクエストにヘッダーを追加する必要があります。 <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>Jinja2テンプレートでCSRF保護を利用する<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 の <a class=\"reference internal\" href=\"/ja/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> テンプレートバックエンドは、すべてのテンプレートのコンテキストに <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">csrf_input</span> <span class=\"pre\">}}</span></code> を追加します。これは、Django テンプレート言語内の <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> と同じ意味です。例えば:</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>デコレータメソッドの利用<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>全体を保護するために <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> を追加する代わりに、保護を必要とする特定のビューにおいて、まったく同じ機能を持つ <a class=\"reference internal\" href=\"/ja/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> デコレータを使えます。アウトプット内に CSRF トークンを挿入するビューと、POST フォームデータを受け入れるビューの両方で使用する必要があります (多くの場合同じビュー関数ですが、そうでない場合もあります)。</p>\n<p>デコレータ自体で使うことは <strong>非推奨</strong> です。もし使い忘れた場合、セキュリティホールを抱えることになるからです。二重対策として両方を使うのは構いませんが、わずかにオーバーヘッドが増加します。</p>\n</section>\n<section id=\"handling-rejected-requests\">\n<span id=\"csrf-rejected-requests\"></span><h2>リクエスト拒否に対処する<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>デフォルトでは、受信リクエストが <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> によって実行されるチェックに失敗した場合、ユーザーには &quot;403 Forbidden&quot; レスポンスが送信されます。これは通常、実際の CSRF が発生した場合、またはプログラミングエラーにより POST フォームに CSRF トークンが含まれていない場合にのみ送信されるべきです。</p>\n<p>エラーページはとてもユーザーフレンドリーではないので、独自のビューを提供したいと考えるかもしれません。<a class=\"reference internal\" href=\"/ja/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>CSRF の認証失敗は、 <a class=\"reference internal\" href=\"/ja/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>キャッシュによるCSRF保護を利用する<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><a class=\"reference internal\" href=\"/ja/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> テンプレートタグがテンプレートで使用されている場合(または <code class=\"docutils literal notranslate\"><span class=\"pre\">get_token</span></code> 関数が他の方法で呼び出されている場合)、<code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> はレスポンスにクッキーと <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary:</span> <span class=\"pre\">Cookie</span></code> ヘッダをレスポンスに追加します。これは、<code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> が指示通りに使用された場合、このミドルウェアがキャッシュミドルウェアと協調的に動作することを意味します（ <code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> は他のすべてのミドルウェアよりも優先されます）。</p>\n<p>しかし、個々のビューでキャッシュデコレータを使用すると、CSRF ミドルウェアはまだ Vary ヘッダや CSRF クッキーを設定できておらず、レスポンスはどちらも設定されずにキャッシュされます。この場合、CSRF トークンを挿入する必要があるビューでは、 <a class=\"reference internal\" href=\"/ja/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> デコレータを最初に使うべきです:</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>クラスベースのビューを使っている場合は、<a class=\"reference internal\" href=\"/ja/6.1/topics/class-based-views/intro/#id1\"><span class=\"std std-ref\">Decorating class-based views</span></a> を参照してください。</p>\n</section>\n<section id=\"testing-and-csrf-protection\">\n<h2>テストと CSRF 保護<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>通常、 <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> はビュー関数をテストする際に大きな障害となります。なぜなら、 POST リクエストごとに CSRF トークンを送信する必要があるからです。このため、Django のテスト用 HTTP クライアントは、ミドルウェアと <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> デコレータを緩和するフラグをリクエストに設定するように変更されました。それ以外の点 (例えばクッキーの送信など) では同じように動作します。</p>\n<p>何らかの理由でテストクライアントに CSRF チェックを実行して <em>ほしい</em> ときには、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>エッジケース<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>ビューによっては、ここで想定している通常のパターンに当てはまらないような特殊な要求がある場合があります。このような状況では、多くのユーティリティが役に立ちます。それらが必要とされる可能性のあるシナリオについては、次のセクションで説明します。</p>\n<section id=\"disabling-csrf-protection-for-just-a-few-views\">\n<h3>特定のビューで CSRF 保護を無効化する<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>ほとんどのビューでCSRF保護が必要だが、わずかのビューでは必要でないケースがあります。</p>\n<p>解決策: ミドルウェアを無効にして、必要なビュー全てに <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> を適用するのではなく、ミドルウェアを有効にして <a class=\"reference internal\" href=\"/ja/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><code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view()</span></code> が使われない場合のトークン設定<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>ビューが実行される前に <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view</span></code> が実行されない場合があります（例えば、404ハンドラーや500ハンドラー）その場合でもフォームでCSRFトークンが必要となる場合。</p>\n<p>解決策: <a class=\"reference internal\" href=\"/ja/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>保護されていないビューにCSRFトークンを含める<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><code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_exempt</span></code> によって除外され、保護されていないビューがあるかもしれない中で、CSRFトークンを含めなければならないこともあります。</p>\n<p>解決策: <a class=\"reference internal\" href=\"/ja/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> の後に続けて <a class=\"reference internal\" href=\"/ja/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> を使用してください (つまり、 <code class=\"docutils literal notranslate\"><span class=\"pre\">requires_csrf_token</span></code> が最も内側のデコレータとなるようにしてください)。</p>\n</section>\n<section id=\"protecting-a-view-for-only-one-path\">\n<h3>1つのパスに対してのみビューを保護する<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>ビューが CSRF 保護を必要とするのは、ある条件のときだけで、それ以外のときは CSRF 保護をしてはいけないときがあります。</p>\n<p>解決方法: ビュー関数全体には <a class=\"reference internal\" href=\"/ja/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> を使用し、その中で保護が必要なパスに対して <a class=\"reference internal\" href=\"/ja/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> を使用します。例えば:</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>HTML フォームなしで AJAX を使用するページの保護<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>AJAX 経由で POST リクエストを行うページにおいて、必要な CSRF クッキーを送信する <a class=\"reference internal\" href=\"/ja/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> を持つ HTML フォームがないことがあります。</p>\n<p>解決策: ページを送信するビューで <a class=\"reference internal\" href=\"/ja/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</section>\n</section>\n<section id=\"csrf-protection-in-reusable-applications\">\n<h2>再利用可能なアプリケーションにおける CSRF 保護<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>開発者は <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> を個別にオフにすることができるので、CSRF に対するアプリケーションのセキュリティを保証するために、contrib アプリケーションの関連するビューには、すべて <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> デコレータを適用しています。その他の再利用可能なアプリの開発者も、同様にセキュリティを保証したいのであれば、ビューに <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> デコレータを適用してください。</p>\n</section>","rootId":"how-to-use-django-s-csrf-protection","toc":[{"title":"AJAXでCSRF保護を利用する","anchor":"using-csrf-protection-with-ajax","children":[{"title":"CSRF_USE_SESSIONS と CSRF_COOKIE_HTTPONLY が False に設定されている場合にトークンを取得する","anchor":"acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false","children":[]},{"title":"CSRF_USE_SESSIONS または CSRF_COOKIE_HTTPONLY が True の時トークンを取得する","anchor":"acquiring-the-token-if-csrf-use-sessions-or-csrf-cookie-httponly-is-true","children":[]},{"title":"AJAX 通信でトークンを設定する","anchor":"setting-the-token-on-the-ajax-request","children":[]}]},{"title":"Jinja2テンプレートでCSRF保護を利用する","anchor":"using-csrf-protection-in-jinja2-templates","children":[]},{"title":"デコレータメソッドの利用","anchor":"using-the-decorator-method","children":[]},{"title":"リクエスト拒否に対処する","anchor":"handling-rejected-requests","children":[]},{"title":"キャッシュによるCSRF保護を利用する","anchor":"using-csrf-protection-with-caching","children":[]},{"title":"テストと CSRF 保護","anchor":"testing-and-csrf-protection","children":[]},{"title":"エッジケース","anchor":"edge-cases","children":[{"title":"特定のビューで CSRF 保護を無効化する","anchor":"disabling-csrf-protection-for-just-a-few-views","children":[]},{"title":"CsrfViewMiddleware.process_view() が使われない場合のトークン設定","anchor":"setting-the-token-when-csrfviewmiddleware-process-view-is-not-used","children":[]},{"title":"保護されていないビューにCSRFトークンを含める","anchor":"including-the-csrf-token-in-an-unprotected-view","children":[]},{"title":"1つのパスに対してのみビューを保護する","anchor":"protecting-a-view-for-only-one-path","children":[]},{"title":"HTML フォームなしで AJAX を使用するページの保護","anchor":"protecting-a-page-that-uses-ajax-without-an-html-form","children":[]}]},{"title":"再利用可能なアプリケーションにおける CSRF 保護","anchor":"csrf-protection-in-reusable-applications","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"How-to ガイド","url":"/ja/6.1/howto/"}],"prev":{"docname":"howto/csp","title":"How to use Django's Content Security Policy","url":"/ja/6.1/howto/csp/"},"next":{"docname":"howto/custom-file-storage","title":"カスタムのストレージクラスを書く","url":"/ja/6.1/howto/custom-file-storage/"},"formats":{"html":"/ja/6.1/howto/csrf/","markdown":"/ja/6.1/howto/csrf.md","json":"/ja/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/ja/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"]}