ミドルウェア¶
このドキュメントでは、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 に準拠するために弱い形式になります。
gzip_page()
デコレータを使用して、個別のビューに GZip 圧縮を適用できます。
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
ブラウザに対し、同一オリジンのリンクについては完全なURLを送信するよう指示します。クロスオリジンのリンクに対しては、リファラは送信されません。
strict-origin
ブラウザに、プロトコルのダウングレードが発生した場合に、完全なURLではなくオリジンのみを送信するよう指示し、リファラを送信しないようにします。
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として解釈されてしまう恐れがあります。
ブラウザがコンテンツタイプを推測し、常に Content-Type
ヘッダーで提供されたタイプを使用するように強制するために、X-Content-Type-Options: nosniff ヘッダーを渡すことができます。 SECURE_CONTENT_TYPE_NOSNIFF
設定が True
であれば、 SecurityMiddleware
は全てのレスポンスに対してこれを行います。
ほとんどのデプロイ状況では、ユーザーがアップロードしたファイルの配信に 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¶
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
の後に置きます。 -
New in Django 5.1.
user オブジェクトを使うので、
AuthenticationMiddleware
の後に置きます。 -
session ベースの storage を使うので、
SessionMiddleware
の後に置きます。 -
キャッシュのハッシュキーを生成するのに
Vary
ヘッダを使用するため、このヘッダを修正するすべてのミドルウェアのあとに置きます。 -
最後に実行されるタイプのミドルウェアなので、できるだけ下に置く必要があります。
-
最後に実行されるタイプのミドルウェアなので、できるだけ下に置く必要があります。