ミドルウェア¶
このドキュメントでは、Djangoに付属するすべてのミドルウェアコンポーネントについて説明します。それらの使用方法や独自のミドルウェアの作成方法についての情報は、 ミドルウェア使用ガイド を参照してください。
使用できる middleware¶
Cache middleware¶
サイト全体でキャッシュを有効にします。有効にすると、Django を利用している各ページは CACHE_MIDDLEWARE_SECONDS 設定で指定した時間だけキャッシュされます。詳しくは キャッシュのドキュメント を参照してください。
Common middleware¶
- class CommonMiddleware[ソース]¶
- response_redirect_class¶
デフォルトは
HttpResponsePermanentRedirectです。ミドルウェアが発行するリダイレクトをカスタマイズするには、CommonMiddlewareをサブクラス化し、この属性をオーバーライドします。
完璧主義者のためにいくつかの便利な機能を提供します。
DISALLOWED_USER_AGENTS設定に含まれるユーザーエージェントのアクセスを禁止します。この設定は、コンパイルした正規表現オブジェクトのリストである必要があります。APPEND_SLASHおよびPREPEND_WWW設定に基づいて、URL の書き換えを実行します。APPEND_SLASHがTrueで、与えられた URL がスラッシュで終わっていなくて、さらに URLconf に URL が見つからなければ、Django は / が最後に追加された新しい URL を作り、この新しい URL へリクエストをリダイレクトします。それ以外のときには、最初の URL を通常通りに処理します。たとえば、
foo.com/barは、foo.com/barに対する有効な URL パタンがなく、foo.com/bar/に対しては有効なパタンが 存在する 場合に、foo.com/bar/にリダイレクトされます。PREPEND_WWWをTrueにすると、先頭に "www." がない URL は "www." で始まる同じ URL にリダイレクトされます。2つのオプションが意味するのは、URL を正規化するということです。これは、1つの URL には1つの、かつただ1つだけの場所を指すべきだという考えです。技術的には URL
foo.com/barはfoo.com/bar/とは区別されます。実際、サーチエンジンのインデクスはこれらを区別して作成されます。よって、URL を正規化するというのがベストプラクティスなのです。必要に応じて、個々のビューは、
no_append_slash()デコレータを使用して、APPEND_SLASHの動作から除外できます。from django.views.decorators.common import no_append_slash @no_append_slash def sensitive_fbv(request, *args, **kwargs): """View to be excluded from APPEND_SLASH.""" return HttpResponse()
非ストリーミングレスポンスに対して
Content-Lengthヘッダを設定します。
壊れたリンクの通知メールを
MANAGERSに送信します (詳細は エラーレポートの管理 を参照)。
GZip middleware¶
- class GZipMiddleware[ソース]¶
- max_random_bytes¶
デフォルトは 100 です。 圧縮されたレスポンスに含まれるランダムバイトの最大数を変更するには、
GZipMiddlewareをサブクラス化して属性をオーバーライドしてください。
注釈
セキュリティ研究者たちは、Webサイトで GZipMiddleware を含む圧縮技術が使用されると、そのサイトが多くの潜在的な攻撃にさらされる可能性があることを明らかにしました。
攻撃を軽減するために、Django は Heal The Breach (HTB) と呼ばれる技術を実装しています。攻撃の効果を軽減するため、各レスポンスに最大で 100 バイトまでのランダムなバイト (詳細は max_random_bytes を参照) を追加します。
詳細については、 BREACH paper (PDF) 、breachattack.com、そして Heal The Breach (HTB) paper を参照してください。
django.middleware.gzip.GZipMiddleware は、GZip 圧縮に対応したブラウザ(すべてのモダンブラウザ)のためにコンテンツを圧縮します。
このミドルウェアは、レスポンスボディを読み書きする必要がある他のミドルウェアよりも前に配置するべきです。圧縮がその後に行われるようにするためです。
次のいずれかが当てはまる場合、コンテンツは圧縮されません:
コンテンツ・ボディの長さが200バイト未満。
レスポンスがすでに
Content-Encodingヘッダを設定している。リクエスト(ブラウザ)が
Accept-Encodingヘッダにgzipを含んでいない。
もしレスポンスに ETag ヘッダーがあれば、ETag は、RFC 9110 Section 8.8.1 に準拠するために弱い形式になります。
You can apply GZip compression to individual views using the
gzip_page() decorator.
Conditional GET middleware¶
条件付きGET操作を扱います。レスポンスに ETag ヘッダーがない場合、必要に応じてミドルウェアが追加します。レスポンスに ETag または Last-Modified ヘッダーがあり、リクエストに If-None-Match または If-Modified-Since がある場合、レスポンスは HttpResponseNotModified に置き換えられます。
You can handle conditional GET operations with individual views using the
conditional_page() decorator.
Locale ミドルウェア¶
- class LocaleMiddleware[ソース]¶
- response_redirect_class¶
デフォルトは
HttpResponseRedirectです。LocaleMiddlewareをサブクラス化して属性をオーバーライドし、ミドルウェアによって発行されたリダイレクトをカスタマイズします。
リクエストからのデータに基づいた言語セクションを有効化します。この機能は、それぞれのユーザに対してコンテンツをカスタマイズします。 国際化のドキュメント を参照してください。
Message ミドルウェア¶
クッキーおよびセッションをベースとしたメッセージサポートを有効化します。メッセージのドキュメント を参照してください。
Security middleware¶
警告
デプロイメントの状況によっては、通常、フロントエンドのウェブサーバーが SecurityMiddleware が提供する機能を実行するのが良いです。これにより、Djangoで処理されないリクエスト(静的メディアやユーザーがアップロードしたファイルなど)も、Djangoアプリケーションへのリクエストと同じ保護を受けることができます。
django.middleware.security.SecurityMiddleware は、リクエスト/レスポンスサイクルに複数のセキュリティ強化機能を提供します。それぞれの機能は、設定を使って個別に有効または無効にできます。
HTTP Strict Transport Security¶
HTTPSでのみアクセスする必要のあるサイトでは、 "Strict-Transport-Security" header を設定することで、一定期間、モダンブラウザに対して、セキュアでない接続を通じてドメイン名に接続しないように指示できます。これにより、SSLストリッピング型の中間者攻撃 (MITM) に対するリスクを軽減できます。
SecurityMiddleware は、SECURE_HSTS_SECONDS 設定をゼロ以外の整数値に設定すると、すべての HTTPS レスポンスに対してこのヘッダーを自動的に設定します。
HSTSを有効にする際には、最初に小さい値をテスト用に使用することをお勧めします。たとえば、1時間の場合は SECURE_HSTS_SECONDS = 3600 です。ウェブブラウザがあなたのサイトからHSTSヘッダーを検知するたびに、指定された期間、非セキュアな通信(HTTPを使用)をあなたのドメインと行うことを拒否します。サイト上の全てのアセットが安全に提供されていること(つまり、HSTSが何も壊していないこと)を確認できたら、頻繁でない訪問者も保護されるようにこの値を増やすことをお勧めします(一般的には31536000秒、すなわち1年が普通です)。
また、SECURE_HSTS_INCLUDE_SUBDOMAINS 設定を True に設定すると、SecurityMiddleware は Strict-Transport-Security ヘッダーに includeSubDomains ディレクティブを追加します。これは推奨です (すべてのサブドメインが HTTPS を使用してのみ提供されている場合)。それ以外の場合、サイトはまだサブドメインへの安全でない接続を介して脆弱になる可能性があります。
browser preload list にサイトを登録する場合は、 SECURE_HSTS_PRELOAD 設定を True に設定してください。これにより、 Strict-Transport-Security ヘッダーに preload ディレクティブが追加されます。
警告
HSTSポリシーは、ヘッダーを設定したレスポンスのURLだけでなく、ドメイン全体に適用されます。したがって、ドメイン全体がHTTPS経由のみで提供される場合にのみ使用すべきです。
HSTSヘッダーを適切に尊重するブラウザは、期限切れ、自己署名、またはその他の無効なSSL証明書を持つサイトに警告をバイパスして接続することをユーザーに許可しません。HSTSを使用する場合は、証明書が適切な状態にあることを確認し、維持してください!
注釈
ロードバランサーやリバースプロキシサーバーの後ろに配置されている場合、そして Strict-Transport-Security ヘッダーがレスポンスに追加されていない場合は、Djangoが安全な接続上にあることを認識していない可能性があります。その場合、SECURE_PROXY_SSL_HEADER 設定を行う必要があるかもしれません。
リファラ・ポリシー¶
ブラウザは、ユーザーがどのようにそのサイトに到達したかについての情報をサイトに送信する手段として、 the Referer header を使用します。ユーザーがリンクをクリックすると、ブラウザはリファラとしてリンク元ページの完全な URL を送信します。これにより、誰があなたのサイトにリンクしているかを特定するなどの目的には役立ちますが、同時に、ユーザーが別のサイトを訪れていたことを1つのサイトに通知することでプライバシー上の懸念が引き起こされる可能性もあります。
一部のブラウザには、ユーザーがリンクをクリックした際に HTTP Referer ヘッダを送信すべきかについてのヒントを受け入れる機能があります。このヒントは the Referrer-Policy header を介して提供されます。このヘッダは、ブラウザに対して3つの動作のいずれかを提案できます:
完全なURL:
Refererヘッダーには、完全なURLを送信します。たとえば、ユーザーがhttps://example.com/page.htmlを訪問している場合、Refererヘッダーには"https://example.com/page.html"が含まれます。Origin のみ: referrerには "origin" のみを送信します。origin はスキーム、ホスト、(オプションで) ポート番号から構成されます。例えば、ユーザーが
https://example.com/page.htmlを訪問している場合、origin はhttps://example.com/となります。リファラなし:
Refererヘッダーを一切送信しません。
このヘッダーがブラウザーに注意を促す条件は2種類あります:
同一オリジンとクロスオリジン:
https://example.com/1.htmlからhttps://example.com/2.htmlへのリンクは同一オリジンです。https://example.com/page.htmlからhttps://not.example.com/page.htmlへのリンクはクロスオリジンです。プロトコルのダウングレード: リンクを含むページがHTTPS経由で提供されている場合、リンク先のページがHTTPS経由で提供されていない場合にダウングレードが発生します。
警告
サイトが HTTPS 経由で提供される場合、Django の CSRF 保護システム は Referer ヘッダーが存在することを要求するので、Referer ヘッダーを完全に無効にすることは CSRF 保護の妨げになります。 Referer ヘッダーを無効にすることの多くの利点を享受しつつ、CSRF 保護も維持するには、同一オリジンのリファラーのみを有効にすることを検討してください。
SecurityMiddleware は、SECURE_REFERRER_POLICY 設定に基づいて Referrer-Policy ヘッダを設定できます(スペルに注意: ブラウザはユーザーがリンクをクリックすると Referer ヘッダを送信しますが、ブラウザにこれを行うかどうかを指示するヘッダは Referrer-Policy と綴られます)。この設定の有効な値は次の通りです:
no-referrerこのサイト上でクリックされたリンクに対して、ブラウザにリファラを送信しないよう指示します。
no-referrer-when-downgradeブラウザに、プロトコルのダウングレードが発生しない時にのみ、完全なURLをリファラとして送信するよう指示します。
originブラウザに、リファラとして完全な URL ではなく、オリジンのみを送信するよう指示します。
origin-when-cross-originブラウザに、同一オリジンのリンクでは完全なURLをリファラとして送信するように指示し、クロスオリジンのリンクではオリジンのみを送信するようにします。
same-origin Instructs the browser to send a full URL, but only for
same-origin links. No referrer will be sent for cross-origin links.
strict-origin Instructs the browser to send only the origin, not the full
URL, and to send no referrer when a protocol downgrade occurs.
strict-origin-when-cross-origin同一オリジンでプロトコルのダウングレードが発生しない場合、ブラウザには完全なURLを送信するよう指示します。クロスオリジンでプロトコルのダウングレードが発生しない場合、ブラウザにはオリジンのみを送信するよう指示します。プロトコルのダウングレードが発生する場合はリファラを送信しません。
unsafe-urlブラウザに常に完全なURLをリファラとして送信するよう指示します。
ポリシーの値が unknown の場合
ユーザーエージェントによってポリシー値が unknown とされた場合、フォールバックを提供するために複数のポリシー値を指定できます。解釈可能な最後に指定された値が優先されます。これをサポートするために、イテラブルもしくはカンマで区切られた文字列が SECURE_REFERRER_POLICY の設定として使用できます。
同一生成元ポリシー (Cross-Origin Opener Policy)¶
一部のブラウザは、 Cross-Origin Opener Policy (COOP) ヘッダーの値に基づいて、トップレベルウィンドウを他のドキュメントから分離する能力を持っています。この分離によって、特定のドキュメントがクロスオリジンのポップアップウィンドウを開いた場合、そのポップアップの window.opener プロパティは null になります。COOP を使用したウィンドウの分離は、特に Spectre のような、共有されたブラウジングコンテキストに読み込まれたデータの外部への持ち出しを可能にしたクロスオリジン攻撃に対する深層防御保護です。
SecurityMiddleware は、 SECURE_CROSS_ORIGIN_OPENER_POLICY 設定に基づいて、 Cross-Origin-Opener-Policy ヘッダーを設定できます。この設定の有効な値は以下の通りです:
same-origin同じオリジンのドキュメントに閲覧コンテキストを排他的に限定します。異なるオリジンのドキュメントは同じ閲覧コンテキストで読み込まれません。これがデフォルトで最も安全なオプションです。
same-origin-allow-popupsブラウジングコンテキストを同一オリジンのドキュメントに限定します。または、COOP を設定しないドキュメントや、COOP を
unsafe-noneに設定して隔離からオプトアウトするドキュメントに限定します。unsafe-noneドキュメントを、オープナー自体が
same-originまたはsame-origin-allow-popupsのCOOPを持っている場合を除いて、そのオープナーのブラウジングコンテキストグループに追加できるようにします。
X-Content-Type-Options: nosniff¶
一部のブラウザーは、取得したアセットのコンテンツタイプを推測し、 Content-Type ヘッダーを上書きしようとします。これは不適切に設定されたサーバーのサイトを表示する際に役立つことがありますが、セキュリティリスクをもたらすこともあります。
サイトがユーザーがアップロードしたファイルを提供する場合、悪意のあるユーザーが特別に作成したファイルをアップロードする可能性があります。そのファイルが無害なものだと思っていたのに、ブラウザでHTMLまたはJavaScriptとして解釈されてしまう恐れがあります。
To prevent the browser from guessing the content type and force it to
always use the type provided in the Content-Type header, you can pass
the X-Content-Type-Options: nosniff header. SecurityMiddleware will
do this for all responses if the SECURE_CONTENT_TYPE_NOSNIFF setting
is True.
ほとんどのデプロイ状況では、ユーザーがアップロードしたファイルの配信に Django が関与しないため、この設定は助けになりません。たとえば、MEDIA_URL がフロントエンドのウェブサーバー (nginx や Apache など) から直接配信される場合は、このヘッダーを設定することをおすすめします。一方で、たとえばもし認可が必要なファイルをダウンロードするために Django を使用していて、ウェブサーバーを使ってヘッダーを設定することができない場合、この設定が役に立つでしょう。
SSL リダイレクト¶
サイトが HTTP と HTTPS 接続の両方をサポートしている場合、多くのユーザーはデフォルトでセキュアでない接続を行ってしまいます。最善のセキュリティのためには、すべての HTTP 接続を HTTPS 接続にリダイレクトするべきです。
SECURE_SSL_REDIRECT 設定を True に設定すれば、 SecurityMiddleware が すべての HTTP 接続を HTTPS に parmanent (HTTP 301) にリダイレクトしてくれます。
注釈
パフォーマンス上の理由により、このようなリダイレクトは Django の外部、フロントエンドのロードバランサーや nginx などのリバースプロキシサーバーで実行した方が良いです。 SECURE_SSL_REDIRECT は、これらのオプションが使用できないデプロイ環境で使われることを想定しています。
SECURE_SSL_HOST 設定に値がある場合、全てのリダイレクトは元々要求されたホストではなく、その値で指定されたホストに送信されます。
サイトのいくつかのページをHTTP経由で利用可能にし、HTTPSにリダイレクトされないようにしたい場合は、 SECURE_REDIRECT_EXEMPT 設定にそれらのURLに一致する正規表現をリストアップできます。
注釈
ロードバランサーやリバースプロキシサーバーの後ろにデプロイしており、Django がリクエストが既に安全であるかどうかを正しく判断できない場合は、 SECURE_PROXY_SSL_HEADER 設定を行う必要があります。
Session middleware¶
セッションのサポートを有効にします。詳しくは セッションのドキュメント を読んでください。
Site ミドルウェア¶
受信側のすべての HttpRequest オブジェクトに、現在のサイトを表す site 属性を追加します。詳しくは sites のドキュメント を参照してください。
Authentication middleware¶
HttpRequest オブジェクトに対して、現在ログインしているユーザーを表す user 属性を追加します。ウェブリクエストにおける認証 を参照してください。
- class LoginRequiredMiddleware[ソース]¶
ミドルウェアをサブクラス化し、以下の属性やメソッドをオーバーライドすることで、認証されていないリクエストに対する動作をカスタマイズできます。
- redirect_field_name¶
デフォルトは
"next"です。
- get_login_url()[ソース]¶
認証されていないリクエストがリダイレクトされる URL を返します。この結果は、
login_required()デコレーターで設定されたlogin_url``(もし ``Noneでない場合)か、またはsettings.LOGIN_URLになります。
- get_redirect_field_name()[ソース]¶
ログインが成功した後にユーザーがリダイレクトされるべき URL を含むクエリパラメータの名前を返します。この結果は、
login_required()デコレーターで設定されたredirect_field_name``(もし ``Noneでない場合)か、またはredirect_field_nameになります。Noneが返される場合、クエリパラメータは追加されません。
認証されていないリクエストはすべてログインページにリダイレクトされますが、login_not_required() で除外されたビューはリダイレクトされません。ログインページのデフォルトは settings.LOGIN_URL ですが、カスタマイズ可能です。
このミドルウェアを有効にするには、MIDDLEWARE 設定に AuthenticationMiddleware の 後に 追加します。
MIDDLEWARE = [
"...",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.auth.middleware.LoginRequiredMiddleware",
"...",
]
ビューを公開して、認証されていないリクエストを許可するには、login_not_required() を使用します。たとえば次のようにします。
from django.contrib.auth.decorators import login_not_required
@login_not_required
def contact_us(request): ...
認証済みのビューのログイン URL やフィールド名をカスタマイズするには、login_required() デコレーターでそれぞれ login_url や redirect_field_name を設定します。たとえば次のようにします。
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import View
@login_required(login_url="/books/login/", redirect_field_name="redirect_to")
def book_dashboard(request): ...
@method_decorator(
login_required(login_url="/books/login/", redirect_field_name="redirect_to"),
name="dispatch",
)
class BookMetrics(View):
pass
ログインビューでログインを要求しないようにしてください。
無限リダイレクトを防ぐために、ログインビューへの 認証されていないリクエストを許可してください 。
Web サーバーが提供する認証を利用するためのミドルウェアです。使用方法の詳細については REMOTE_USER で認証する を参照してください。
ログインページでのみ有効にした場合の、Webサーバー提供の認証を利用するためのミドルウェアです。使い方の詳細については、 ログインページでのみ REMOTE_USER を使用する を参照してください。
CSRF プロテクション middleware¶
POST フォームに隠しフォームフィールドを追加し、リクエストの値が正しいかチェックすることで、Cross Site Request Forgery に対するプロテクションを追加します。詳しくは Cross Site Request Forgery プロテクションのドキュメント を読んでください。
You can add Cross Site Request Forgery protection to individual views using the
csrf_protect() decorator.
X-Frame-Options middleware¶
Content Security Policy middleware¶
Adds support for Content Security Policy (CSP), which helps mitigate risks such as Cross-Site Scripting (XSS) and data injection attacks by controlling the sources of content that can be loaded in the browser. See the 概要 documentation for details on configuring policies.
This middleware sets the following headers on the response depending on the available settings:
Content-Security-Policy, based onSECURE_CSP.Content-Security-Policy-Report-Only, based onSECURE_CSP_REPORT_ONLY.
Middleware の順序¶
Django の多様なミドルウェアクラスの順序に関する注意点を挙げておきます。
-
SSL リダイレクトを有効にしているなら、他のたくさんの必要のないミドルウェアが実行されないように、リストの先頭付近に置くべきです。
-
Varyヘッダに変更を加えるミドルウェア (SessionMiddleware,GZipMiddleware,LocaleMiddleware) の前に置きます。 -
response body を変更・使用する可能性のあるミドルウェアの前に置きます。
Varyヘッダを修正するため、UpdateCacheMiddlewareの後に置きます。 -
CSRF_USE_SESSIONSを使用している場合、例えばPermissionDeniedのようなエラービューをトリガーする例外を発生させる可能性のあるミドルウェアよりも前に配置してください。Varyヘッダを修正するため、UpdateCacheMiddlewareの後に置きます。 -
レスポンスを変更する可能性があるミドルウェアよりも前に設定してください (これは
ETagヘッダを設定します)。gzip されたコンテンツに対して
ETagヘッダを計算しないように、GZipMiddlewareの後に置きます。 -
SessionMiddleware(session データを使う) とUpdateCacheMiddleware(Varyヘッダを修正する) の後のできるだけ高い位置に置きます。 -
レスポンスを変更する可能性のあるミドルウェアの前に配置します (
Content-Lengthヘッダーを設定します)。CommonMiddlewareの前に配置され、レスポンスを変更するミドルウェアは、Content-Lengthをリセットする必要があります。APPEND_SLASHかPREPEND_WWWがTrueに設定されているとリダイレクトされるので、先頭の近くに置きます。SessionMiddlewareの後に、CSRF_USE_SESSIONSを使用している場合。 -
CSRF 攻撃が可能なすべての view ミドルウェアの前に置きます。
RemoteUserMiddlewareの前、あるいはログインを実行し、CSRF トークンをローテートする可能性のある他の認証ミドルウェアの前、ミドルウェアチェインを呼び出す前に置きます。SessionMiddlewareの後に、CSRF_USE_SESSIONSを使用している場合。 -
session ストレージを使うので、
SessionMiddlewareの後に置きます。 -
user オブジェクトを使うので、
AuthenticationMiddlewareの後に置きます。 -
session ベースの storage を使うので、
SessionMiddlewareの後に置きます。 -
キャッシュのハッシュキーを生成するのに
Varyヘッダを使用するため、このヘッダを修正するすべてのミドルウェアのあとに置きます。 ContentSecurityPolicyMiddlewareCan be placed near the bottom, but ensure any middleware that accesses csp_nonce is positioned after it, so the nonce is properly included in the response header.
-
最後に実行されるタイプのミドルウェアなので、できるだけ下に置く必要があります。
-
最後に実行されるタイプのミドルウェアなので、できるだけ下に置く必要があります。