mirror of https://github.com/django/django.git
604 lines
23 KiB
Plaintext
604 lines
23 KiB
Plaintext
==========
|
||
Middleware
|
||
==========
|
||
|
||
.. module:: django.middleware
|
||
:synopsis: Django's built-in middleware classes.
|
||
|
||
This document explains all middleware components that come with Django. For
|
||
information on how to use them and how to write your own middleware, see
|
||
the :doc:`middleware usage guide </topics/http/middleware>`.
|
||
|
||
Available middleware
|
||
====================
|
||
|
||
Cache middleware
|
||
----------------
|
||
|
||
.. module:: django.middleware.cache
|
||
:synopsis: Middleware for the site-wide cache.
|
||
|
||
.. class:: UpdateCacheMiddleware
|
||
|
||
.. class:: FetchFromCacheMiddleware
|
||
|
||
Enable the site-wide cache. If these are enabled, each Django-powered page will
|
||
be cached for as long as the :setting:`CACHE_MIDDLEWARE_SECONDS` setting
|
||
defines. See the :doc:`cache documentation </topics/cache>`.
|
||
|
||
"Common" middleware
|
||
-------------------
|
||
|
||
.. module:: django.middleware.common
|
||
:synopsis: Middleware adding "common" conveniences for perfectionists.
|
||
|
||
.. class:: CommonMiddleware
|
||
|
||
Adds a few conveniences for perfectionists:
|
||
|
||
* Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS`
|
||
setting, which should be a list of compiled regular expression objects.
|
||
|
||
* Performs URL rewriting based on the :setting:`APPEND_SLASH` and
|
||
:setting:`PREPEND_WWW` settings.
|
||
|
||
If :setting:`APPEND_SLASH` is ``True`` and the initial URL doesn't end
|
||
with a slash, and it is not found in the URLconf, then a new URL is
|
||
formed by appending a slash at the end. If this new URL is found in the
|
||
URLconf, then Django redirects the request to this new URL. Otherwise,
|
||
the initial URL is processed as usual.
|
||
|
||
For example, ``foo.com/bar`` will be redirected to ``foo.com/bar/`` if
|
||
you don't have a valid URL pattern for ``foo.com/bar`` but *do* have a
|
||
valid pattern for ``foo.com/bar/``.
|
||
|
||
If :setting:`PREPEND_WWW` is ``True``, URLs that lack a leading "www."
|
||
will be redirected to the same URL with a leading "www."
|
||
|
||
Both of these options are meant to normalize URLs. The philosophy is that
|
||
each URL should exist in one, and only one, place. Technically a URL
|
||
``foo.com/bar`` is distinct from ``foo.com/bar/`` -- a search-engine
|
||
indexer would treat them as separate URLs -- so it's best practice to
|
||
normalize URLs.
|
||
|
||
If necessary, individual views may be excluded from the ``APPEND_SLASH``
|
||
behavior using the :func:`~django.views.decorators.common.no_append_slash`
|
||
decorator::
|
||
|
||
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()
|
||
|
||
* Sets the ``Content-Length`` header for non-streaming responses.
|
||
|
||
.. attribute:: CommonMiddleware.response_redirect_class
|
||
|
||
Defaults to :class:`~django.http.HttpResponsePermanentRedirect`. Subclass
|
||
``CommonMiddleware`` and override the attribute to customize the redirects
|
||
issued by the middleware.
|
||
|
||
.. class:: BrokenLinkEmailsMiddleware
|
||
|
||
* Sends broken link notification emails to :setting:`MANAGERS` (see
|
||
:doc:`/howto/error-reporting`).
|
||
|
||
GZip middleware
|
||
---------------
|
||
|
||
.. module:: django.middleware.gzip
|
||
:synopsis: Middleware to serve GZipped content for performance.
|
||
|
||
.. class:: GZipMiddleware
|
||
|
||
.. warning::
|
||
|
||
Security researchers recently revealed that when compression techniques
|
||
(including ``GZipMiddleware``) are used on a website, the site may become
|
||
exposed to a number of possible attacks. Before using ``GZipMiddleware`` on
|
||
your site, you should consider very carefully whether you are subject to
|
||
these attacks. If you're in *any* doubt about whether you're affected, you
|
||
should avoid using ``GZipMiddleware``. For more details, see the `the BREACH
|
||
paper (PDF)`_ and `breachattack.com`_.
|
||
|
||
.. _the BREACH paper (PDF): http://breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf
|
||
.. _breachattack.com: http://breachattack.com
|
||
|
||
The ``django.middleware.gzip.GZipMiddleware`` compresses content for browsers
|
||
that understand GZip compression (all modern browsers).
|
||
|
||
This middleware should be placed before any other middleware that need to
|
||
read or write the response body so that compression happens afterward.
|
||
|
||
It will NOT compress content if any of the following are true:
|
||
|
||
* The content body is less than 200 bytes long.
|
||
|
||
* The response has already set the ``Content-Encoding`` header.
|
||
|
||
* The request (the browser) hasn't sent an ``Accept-Encoding`` header
|
||
containing ``gzip``.
|
||
|
||
If the response has an ``ETag`` header, the ETag is made weak to comply with
|
||
:rfc:`7232#section-2.1`.
|
||
|
||
You can apply GZip compression to individual views using the
|
||
:func:`~django.views.decorators.gzip.gzip_page()` decorator.
|
||
|
||
Conditional GET middleware
|
||
--------------------------
|
||
|
||
.. module:: django.middleware.http
|
||
:synopsis: Middleware handling advanced HTTP features.
|
||
|
||
.. class:: ConditionalGetMiddleware
|
||
|
||
Handles conditional GET operations. If the response doesn't have an ``ETag``
|
||
header, the middleware adds one if needed. If the response has an ``ETag`` or
|
||
``Last-Modified`` header, and the request has ``If-None-Match`` or
|
||
``If-Modified-Since``, the response is replaced by an
|
||
:class:`~django.http.HttpResponseNotModified`.
|
||
|
||
Locale middleware
|
||
-----------------
|
||
|
||
.. module:: django.middleware.locale
|
||
:synopsis: Middleware to enable language selection based on the request.
|
||
|
||
.. class:: LocaleMiddleware
|
||
|
||
Enables language selection based on data from the request. It customizes
|
||
content for each user. See the :doc:`internationalization documentation
|
||
</topics/i18n/translation>`.
|
||
|
||
.. attribute:: LocaleMiddleware.response_redirect_class
|
||
|
||
Defaults to :class:`~django.http.HttpResponseRedirect`. Subclass
|
||
``LocaleMiddleware`` and override the attribute to customize the redirects
|
||
issued by the middleware.
|
||
|
||
Message middleware
|
||
------------------
|
||
|
||
.. module:: django.contrib.messages.middleware
|
||
:synopsis: Message middleware.
|
||
|
||
.. class:: MessageMiddleware
|
||
|
||
Enables cookie- and session-based message support. See the
|
||
:doc:`messages documentation </ref/contrib/messages>`.
|
||
|
||
.. _security-middleware:
|
||
|
||
Security middleware
|
||
-------------------
|
||
|
||
.. module:: django.middleware.security
|
||
:synopsis: Security middleware.
|
||
|
||
.. warning::
|
||
If your deployment situation allows, it's usually a good idea to have your
|
||
front-end web server perform the functionality provided by the
|
||
``SecurityMiddleware``. That way, if there are requests that aren't served
|
||
by Django (such as static media or user-uploaded files), they will have
|
||
the same protections as requests to your Django application.
|
||
|
||
.. class:: SecurityMiddleware
|
||
|
||
The ``django.middleware.security.SecurityMiddleware`` provides several security
|
||
enhancements to the request/response cycle. Each one can be independently
|
||
enabled or disabled with a setting.
|
||
|
||
* :setting:`SECURE_CONTENT_TYPE_NOSNIFF`
|
||
* :setting:`SECURE_CROSS_ORIGIN_OPENER_POLICY`
|
||
* :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS`
|
||
* :setting:`SECURE_HSTS_PRELOAD`
|
||
* :setting:`SECURE_HSTS_SECONDS`
|
||
* :setting:`SECURE_REDIRECT_EXEMPT`
|
||
* :setting:`SECURE_REFERRER_POLICY`
|
||
* :setting:`SECURE_SSL_HOST`
|
||
* :setting:`SECURE_SSL_REDIRECT`
|
||
|
||
.. _http-strict-transport-security:
|
||
|
||
HTTP Strict Transport Security
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
For sites that should only be accessed over HTTPS, you can instruct modern
|
||
browsers to refuse to connect to your domain name via an insecure connection
|
||
(for a given period of time) by setting the `"Strict-Transport-Security"
|
||
header`__. This reduces your exposure to some SSL-stripping man-in-the-middle
|
||
(MITM) attacks.
|
||
|
||
``SecurityMiddleware`` will set this header for you on all HTTPS responses if
|
||
you set the :setting:`SECURE_HSTS_SECONDS` setting to a non-zero integer value.
|
||
|
||
When enabling HSTS, it's a good idea to first use a small value for testing,
|
||
for example, :setting:`SECURE_HSTS_SECONDS = 3600<SECURE_HSTS_SECONDS>` for one
|
||
hour. Each time a web browser sees the HSTS header from your site, it will
|
||
refuse to communicate non-securely (using HTTP) with your domain for the given
|
||
period of time. Once you confirm that all assets are served securely on your
|
||
site (i.e. HSTS didn't break anything), it's a good idea to increase this value
|
||
so that infrequent visitors will be protected (31536000 seconds, i.e. 1 year,
|
||
is common).
|
||
|
||
Additionally, if you set the :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS` setting
|
||
to ``True``, ``SecurityMiddleware`` will add the ``includeSubDomains`` directive
|
||
to the ``Strict-Transport-Security`` header. This is recommended (assuming all
|
||
subdomains are served exclusively using HTTPS), otherwise your site may still
|
||
be vulnerable via an insecure connection to a subdomain.
|
||
|
||
If you wish to submit your site to the `browser preload list`_, set the
|
||
:setting:`SECURE_HSTS_PRELOAD` setting to ``True``. That appends the
|
||
``preload`` directive to the ``Strict-Transport-Security`` header.
|
||
|
||
.. warning::
|
||
The HSTS policy applies to your entire domain, not just the URL of the
|
||
response that you set the header on. Therefore, you should only use it if
|
||
your entire domain is served via HTTPS only.
|
||
|
||
Browsers properly respecting the HSTS header will refuse to allow users to
|
||
bypass warnings and connect to a site with an expired, self-signed, or
|
||
otherwise invalid SSL certificate. If you use HSTS, make sure your
|
||
certificates are in good shape and stay that way!
|
||
|
||
.. note::
|
||
If you are deployed behind a load-balancer or reverse-proxy server, and the
|
||
``Strict-Transport-Security`` header is not being added to your responses,
|
||
it may be because Django doesn't realize that it's on a secure connection;
|
||
you may need to set the :setting:`SECURE_PROXY_SSL_HEADER` setting.
|
||
|
||
__ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
|
||
.. _browser preload list: https://hstspreload.org/
|
||
|
||
.. _referrer-policy:
|
||
|
||
Referrer Policy
|
||
~~~~~~~~~~~~~~~
|
||
|
||
Browsers use `the Referer header`__ as a way to send information to a site
|
||
about how users got there. When a user clicks a link, the browser will send the
|
||
full URL of the linking page as the referrer. While this can be useful for some
|
||
purposes -- like figuring out who's linking to your site -- it also can cause
|
||
privacy concerns by informing one site that a user was visiting another site.
|
||
|
||
__ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer
|
||
|
||
Some browsers have the ability to accept hints about whether they should send
|
||
the HTTP ``Referer`` header when a user clicks a link; this hint is provided
|
||
via `the Referrer-Policy header`__. This header can suggest any of three
|
||
behaviors to browsers:
|
||
|
||
__ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
||
|
||
* Full URL: send the entire URL in the ``Referer`` header. For example, if the
|
||
user is visiting ``https://example.com/page.html``, the ``Referer`` header
|
||
would contain ``"https://example.com/page.html"``.
|
||
|
||
* Origin only: send only the "origin" in the referrer. The origin consists of
|
||
the scheme, host and (optionally) port number. For example, if the user is
|
||
visiting ``https://example.com/page.html``, the origin would be
|
||
``https://example.com/``.
|
||
|
||
* No referrer: do not send a ``Referer`` header at all.
|
||
|
||
There are two types of conditions this header can tell a browser to watch out
|
||
for:
|
||
|
||
* Same-origin versus cross-origin: a link from ``https://example.com/1.html``
|
||
to ``https://example.com/2.html`` is same-origin. A link from
|
||
``https://example.com/page.html`` to ``https://not.example.com/page.html`` is
|
||
cross-origin.
|
||
|
||
* Protocol downgrade: a downgrade occurs if the page containing the link is
|
||
served via HTTPS, but the page being linked to is not served via HTTPS.
|
||
|
||
.. warning::
|
||
When your site is served via HTTPS, :ref:`Django's CSRF protection system
|
||
<how-csrf-works>` requires the ``Referer`` header to be present, so
|
||
completely disabling the ``Referer`` header will interfere with CSRF
|
||
protection. To gain most of the benefits of disabling ``Referer`` headers
|
||
while also keeping CSRF protection, consider enabling only same-origin
|
||
referrers.
|
||
|
||
``SecurityMiddleware`` can set the ``Referrer-Policy`` header for you, based on
|
||
the :setting:`SECURE_REFERRER_POLICY` setting (note spelling: browsers send a
|
||
``Referer`` header when a user clicks a link, but the header instructing a
|
||
browser whether to do so is spelled ``Referrer-Policy``). The valid values for
|
||
this setting are:
|
||
|
||
``no-referrer``
|
||
Instructs the browser to send no referrer for links clicked on this site.
|
||
|
||
``no-referrer-when-downgrade``
|
||
Instructs the browser to send a full URL as the referrer, but only when no
|
||
protocol downgrade occurs.
|
||
|
||
``origin``
|
||
Instructs the browser to send only the origin, not the full URL, as the
|
||
referrer.
|
||
|
||
``origin-when-cross-origin``
|
||
Instructs the browser to send the full URL as the referrer for same-origin
|
||
links, and only the origin for cross-origin links.
|
||
|
||
``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``
|
||
Instructs the browser to send the full URL when the link is same-origin and
|
||
no protocol downgrade occurs; send only the origin when the link is
|
||
cross-origin and no protocol downgrade occurs; and no referrer when a
|
||
protocol downgrade occurs.
|
||
|
||
``unsafe-url``
|
||
Instructs the browser to always send the full URL as the referrer.
|
||
|
||
.. admonition:: Unknown Policy Values
|
||
|
||
Where a policy value is `unknown`__ by a user agent, it is possible to
|
||
specify multiple policy values to provide a fallback. The last specified
|
||
value that is understood takes precedence. To support this, an iterable or
|
||
comma-separated string can be used with :setting:`SECURE_REFERRER_POLICY`.
|
||
|
||
__ https://w3c.github.io/webappsec-referrer-policy/#unknown-policy-values
|
||
|
||
.. _cross-origin-opener-policy:
|
||
|
||
Cross-Origin Opener Policy
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Some browsers have the ability to isolate top-level windows from other
|
||
documents by putting them in a separate browsing context group based on the
|
||
value of the `Cross-Origin Opener Policy`__ (COOP) header. If a document that
|
||
is isolated in this way opens a cross-origin popup window, the popup’s
|
||
``window.opener`` property will be ``null``. Isolating windows using COOP is a
|
||
defense-in-depth protection against cross-origin attacks, especially those like
|
||
Spectre which allowed exfiltration of data loaded into a shared browsing
|
||
context.
|
||
|
||
__ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
|
||
|
||
``SecurityMiddleware`` can set the ``Cross-Origin-Opener-Policy`` header for
|
||
you, based on the :setting:`SECURE_CROSS_ORIGIN_OPENER_POLICY` setting. The
|
||
valid values for this setting are:
|
||
|
||
``same-origin``
|
||
Isolates the browsing context exclusively to same-origin documents.
|
||
Cross-origin documents are not loaded in the same browsing context. This
|
||
is the default and most secure option.
|
||
|
||
``same-origin-allow-popups``
|
||
Isolates the browsing context to same-origin documents or those which
|
||
either don't set COOP or which opt out of isolation by setting a COOP of
|
||
``unsafe-none``.
|
||
|
||
``unsafe-none``
|
||
Allows the document to be added to its opener's browsing context group
|
||
unless the opener itself has a COOP of ``same-origin`` or
|
||
``same-origin-allow-popups``.
|
||
|
||
.. _x-content-type-options:
|
||
|
||
``X-Content-Type-Options: nosniff``
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Some browsers will try to guess the content types of the assets that they
|
||
fetch, overriding the ``Content-Type`` header. While this can help display
|
||
sites with improperly configured servers, it can also pose a security
|
||
risk.
|
||
|
||
If your site serves user-uploaded files, a malicious user could upload a
|
||
specially-crafted file that would be interpreted as HTML or JavaScript by
|
||
the browser when you expected it to be something harmless.
|
||
|
||
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 :setting:`SECURE_CONTENT_TYPE_NOSNIFF` setting
|
||
is ``True``.
|
||
|
||
Note that in most deployment situations where Django isn't involved in serving
|
||
user-uploaded files, this setting won't help you. For example, if your
|
||
:setting:`MEDIA_URL` is served directly by your front-end web server (nginx,
|
||
Apache, etc.) then you'd want to set this header there. On the other hand, if
|
||
you are using Django to do something like require authorization in order to
|
||
download files and you cannot set the header using your web server, this
|
||
setting will be useful.
|
||
|
||
__ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
||
|
||
.. _ssl-redirect:
|
||
|
||
SSL Redirect
|
||
~~~~~~~~~~~~
|
||
|
||
If your site offers both HTTP and HTTPS connections, most users will end up
|
||
with an unsecured connection by default. For best security, you should redirect
|
||
all HTTP connections to HTTPS.
|
||
|
||
If you set the :setting:`SECURE_SSL_REDIRECT` setting to True,
|
||
``SecurityMiddleware`` will permanently (HTTP 301) redirect all HTTP
|
||
connections to HTTPS.
|
||
|
||
.. note::
|
||
|
||
For performance reasons, it's preferable to do these redirects outside of
|
||
Django, in a front-end load balancer or reverse-proxy server such as
|
||
`nginx`_. :setting:`SECURE_SSL_REDIRECT` is intended for the deployment
|
||
situations where this isn't an option.
|
||
|
||
If the :setting:`SECURE_SSL_HOST` setting has a value, all redirects will be
|
||
sent to that host instead of the originally-requested host.
|
||
|
||
If there are a few pages on your site that should be available over HTTP, and
|
||
not redirected to HTTPS, you can list regular expressions to match those URLs
|
||
in the :setting:`SECURE_REDIRECT_EXEMPT` setting.
|
||
|
||
.. note::
|
||
If you are deployed behind a load-balancer or reverse-proxy server and
|
||
Django can't seem to tell when a request actually is already secure, you
|
||
may need to set the :setting:`SECURE_PROXY_SSL_HEADER` setting.
|
||
|
||
.. _nginx: https://nginx.org/
|
||
|
||
Session middleware
|
||
------------------
|
||
|
||
.. module:: django.contrib.sessions.middleware
|
||
:synopsis: Session middleware.
|
||
|
||
.. class:: SessionMiddleware
|
||
|
||
Enables session support. See the :doc:`session documentation
|
||
</topics/http/sessions>`.
|
||
|
||
Site middleware
|
||
---------------
|
||
|
||
.. module:: django.contrib.sites.middleware
|
||
:synopsis: Site middleware.
|
||
|
||
.. class:: CurrentSiteMiddleware
|
||
|
||
Adds the ``site`` attribute representing the current site to every incoming
|
||
``HttpRequest`` object. See the :ref:`sites documentation <site-middleware>`.
|
||
|
||
Authentication middleware
|
||
-------------------------
|
||
|
||
.. module:: django.contrib.auth.middleware
|
||
:synopsis: Authentication middleware.
|
||
|
||
.. class:: AuthenticationMiddleware
|
||
|
||
Adds the ``user`` attribute, representing the currently-logged-in user, to
|
||
every incoming ``HttpRequest`` object. See :ref:`Authentication in web requests
|
||
<auth-web-requests>`.
|
||
|
||
.. class:: RemoteUserMiddleware
|
||
|
||
Middleware for utilizing web server provided authentication. See
|
||
:doc:`/howto/auth-remote-user` for usage details.
|
||
|
||
.. class:: PersistentRemoteUserMiddleware
|
||
|
||
Middleware for utilizing web server provided authentication when enabled only
|
||
on the login page. See :ref:`persistent-remote-user-middleware-howto` for usage
|
||
details.
|
||
|
||
CSRF protection middleware
|
||
--------------------------
|
||
|
||
.. currentmodule:: django.middleware.csrf
|
||
|
||
.. class:: CsrfViewMiddleware
|
||
|
||
Adds protection against Cross Site Request Forgeries by adding hidden form
|
||
fields to POST forms and checking requests for the correct value. See the
|
||
:doc:`Cross Site Request Forgery protection documentation </ref/csrf>`.
|
||
|
||
``X-Frame-Options`` middleware
|
||
------------------------------
|
||
|
||
.. currentmodule:: django.middleware.clickjacking
|
||
|
||
.. class:: XFrameOptionsMiddleware
|
||
|
||
Simple :doc:`clickjacking protection via the X-Frame-Options header </ref/clickjacking/>`.
|
||
|
||
.. _middleware-ordering:
|
||
|
||
Middleware ordering
|
||
===================
|
||
|
||
Here are some hints about the ordering of various Django middleware classes:
|
||
|
||
#. :class:`~django.middleware.security.SecurityMiddleware`
|
||
|
||
It should go near the top of the list if you're going to turn on the SSL
|
||
redirect as that avoids running through a bunch of other unnecessary
|
||
middleware.
|
||
|
||
#. :class:`~django.middleware.cache.UpdateCacheMiddleware`
|
||
|
||
Before those that modify the ``Vary`` header (``SessionMiddleware``,
|
||
``GZipMiddleware``, ``LocaleMiddleware``).
|
||
|
||
#. :class:`~django.middleware.gzip.GZipMiddleware`
|
||
|
||
Before any middleware that may change or use the response body.
|
||
|
||
After ``UpdateCacheMiddleware``: Modifies ``Vary`` header.
|
||
|
||
#. :class:`~django.contrib.sessions.middleware.SessionMiddleware`
|
||
|
||
Before any middleware that may raise an exception to trigger an error
|
||
view (such as :exc:`~django.core.exceptions.PermissionDenied`) if you're
|
||
using :setting:`CSRF_USE_SESSIONS`.
|
||
|
||
After ``UpdateCacheMiddleware``: Modifies ``Vary`` header.
|
||
|
||
#. :class:`~django.middleware.http.ConditionalGetMiddleware`
|
||
|
||
Before any middleware that may change the response (it sets the ``ETag``
|
||
header).
|
||
|
||
After ``GZipMiddleware`` so it won't calculate an ``ETag`` header on gzipped
|
||
contents.
|
||
|
||
#. :class:`~django.middleware.locale.LocaleMiddleware`
|
||
|
||
One of the topmost, after ``SessionMiddleware`` (uses session data) and
|
||
``UpdateCacheMiddleware`` (modifies ``Vary`` header).
|
||
|
||
#. :class:`~django.middleware.common.CommonMiddleware`
|
||
|
||
Before any middleware that may change the response (it sets the
|
||
``Content-Length`` header). A middleware that appears before
|
||
``CommonMiddleware`` and changes the response must reset ``Content-Length``.
|
||
|
||
Close to the top: it redirects when :setting:`APPEND_SLASH` or
|
||
:setting:`PREPEND_WWW` are set to ``True``.
|
||
|
||
After ``SessionMiddleware`` if you're using :setting:`CSRF_USE_SESSIONS`.
|
||
|
||
#. :class:`~django.middleware.csrf.CsrfViewMiddleware`
|
||
|
||
Before any view middleware that assumes that CSRF attacks have been dealt
|
||
with.
|
||
|
||
Before :class:`~django.contrib.auth.middleware.RemoteUserMiddleware`, or any
|
||
other authentication middleware that may perform a login, and hence rotate
|
||
the CSRF token, before calling down the middleware chain.
|
||
|
||
After ``SessionMiddleware`` if you're using :setting:`CSRF_USE_SESSIONS`.
|
||
|
||
#. :class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
|
||
|
||
After ``SessionMiddleware``: uses session storage.
|
||
|
||
#. :class:`~django.contrib.messages.middleware.MessageMiddleware`
|
||
|
||
After ``SessionMiddleware``: can use session-based storage.
|
||
|
||
#. :class:`~django.middleware.cache.FetchFromCacheMiddleware`
|
||
|
||
After any middleware that modifies the ``Vary`` header: that header is used
|
||
to pick a value for the cache hash-key.
|
||
|
||
#. :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`
|
||
|
||
Should be near the bottom as it's a last-resort type of middleware.
|
||
|
||
#. :class:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware`
|
||
|
||
Should be near the bottom as it's a last-resort type of middleware.
|