mirror of https://github.com/django/django.git
Fixed #22185 -- Added settings.CSRF_COOKIE_AGE
Thanks Paul McMillan for the review.
This commit is contained in:
parent
06efeae598
commit
9b729ddd8f
|
@ -558,6 +558,7 @@ CSRF_FAILURE_VIEW = 'django.views.csrf.csrf_failure'
|
|||
|
||||
# Settings for CSRF cookie.
|
||||
CSRF_COOKIE_NAME = 'csrftoken'
|
||||
CSRF_COOKIE_AGE = 60 * 60 * 24 * 7 * 52
|
||||
CSRF_COOKIE_DOMAIN = None
|
||||
CSRF_COOKIE_PATH = '/'
|
||||
CSRF_COOKIE_SECURE = False
|
||||
|
|
|
@ -196,7 +196,7 @@ class CsrfViewMiddleware(object):
|
|||
# the expiry timer.
|
||||
response.set_cookie(settings.CSRF_COOKIE_NAME,
|
||||
request.META["CSRF_COOKIE"],
|
||||
max_age=60 * 60 * 24 * 7 * 52,
|
||||
max_age=settings.CSRF_COOKIE_AGE,
|
||||
domain=settings.CSRF_COOKIE_DOMAIN,
|
||||
path=settings.CSRF_COOKIE_PATH,
|
||||
secure=settings.CSRF_COOKIE_SECURE,
|
||||
|
|
|
@ -491,6 +491,7 @@ Settings
|
|||
|
||||
A number of settings can be used to control Django's CSRF behavior:
|
||||
|
||||
* :setting:`CSRF_COOKIE_AGE`
|
||||
* :setting:`CSRF_COOKIE_DOMAIN`
|
||||
* :setting:`CSRF_COOKIE_HTTPONLY`
|
||||
* :setting:`CSRF_COOKIE_NAME`
|
||||
|
|
|
@ -324,6 +324,28 @@ See :doc:`/topics/cache`.
|
|||
|
||||
.. _settings-csrf:
|
||||
|
||||
.. setting:: CSRF_COOKIE_AGE
|
||||
|
||||
CSRF_COOKIE_AGE
|
||||
---------------
|
||||
|
||||
.. versionadded:: 1.7
|
||||
|
||||
Default: ``31449600`` (1 year, in seconds)
|
||||
|
||||
The age of CSRF cookies, in seconds.
|
||||
|
||||
The reason for setting a long-lived expiration time is to avoid problems in
|
||||
the case of a user closing a browser or bookmarking a page and then loading
|
||||
that page from a browser cache. Without persistent cookies, the form submission
|
||||
would fail in this case.
|
||||
|
||||
Some browsers (specifically Internet Explorer) can disallow the use of
|
||||
persistent cookies or can have the indexes to the cookie jar corrupted on disk,
|
||||
thereby causing CSRF protection checks to fail (and sometimes intermittently).
|
||||
Change this setting to ``None`` to use session-based CSRF cookies, which
|
||||
keep the cookies in-memory instead of on persistent storage.
|
||||
|
||||
.. setting:: CSRF_COOKIE_DOMAIN
|
||||
|
||||
CSRF_COOKIE_DOMAIN
|
||||
|
|
|
@ -446,6 +446,12 @@ Cache
|
|||
"non-expiring" by default. Previously, it was only possible to pass
|
||||
``timeout=None` to the cache backend's ``set()`` method.
|
||||
|
||||
Cross Site Request Forgery
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* The :setting:`CSRF_COOKIE_AGE` setting facilitates the use of session-based
|
||||
CSRF cookies.
|
||||
|
||||
Email
|
||||
^^^^^
|
||||
|
||||
|
|
|
@ -384,3 +384,47 @@ class CsrfViewMiddlewareTest(TestCase):
|
|||
finally:
|
||||
logger.removeHandler(test_handler)
|
||||
logger.setLevel(old_log_level)
|
||||
|
||||
def test_csrf_cookie_age(self):
|
||||
"""
|
||||
Test to verify CSRF cookie age can be set using
|
||||
settings.CSRF_COOKIE_AGE.
|
||||
"""
|
||||
req = self._get_GET_no_csrf_cookie_request()
|
||||
|
||||
MAX_AGE = 123
|
||||
with self.settings(CSRF_COOKIE_NAME='csrfcookie',
|
||||
CSRF_COOKIE_DOMAIN='.example.com',
|
||||
CSRF_COOKIE_AGE=MAX_AGE,
|
||||
CSRF_COOKIE_PATH='/test/',
|
||||
CSRF_COOKIE_SECURE=True,
|
||||
CSRF_COOKIE_HTTPONLY=True):
|
||||
# token_view calls get_token() indirectly
|
||||
CsrfViewMiddleware().process_view(req, token_view, (), {})
|
||||
resp = token_view(req)
|
||||
|
||||
resp2 = CsrfViewMiddleware().process_response(req, resp)
|
||||
max_age = resp2.cookies.get('csrfcookie').get('max-age')
|
||||
self.assertEqual(max_age, MAX_AGE)
|
||||
|
||||
def test_csrf_cookie_age_none(self):
|
||||
"""
|
||||
Test to verify CSRF cookie age does not have max age set and therefore
|
||||
uses session-based cookies.
|
||||
"""
|
||||
req = self._get_GET_no_csrf_cookie_request()
|
||||
|
||||
MAX_AGE = None
|
||||
with self.settings(CSRF_COOKIE_NAME='csrfcookie',
|
||||
CSRF_COOKIE_DOMAIN='.example.com',
|
||||
CSRF_COOKIE_AGE=MAX_AGE,
|
||||
CSRF_COOKIE_PATH='/test/',
|
||||
CSRF_COOKIE_SECURE=True,
|
||||
CSRF_COOKIE_HTTPONLY=True):
|
||||
# token_view calls get_token() indirectly
|
||||
CsrfViewMiddleware().process_view(req, token_view, (), {})
|
||||
resp = token_view(req)
|
||||
|
||||
resp2 = CsrfViewMiddleware().process_response(req, resp)
|
||||
max_age = resp2.cookies.get('csrfcookie').get('max-age')
|
||||
self.assertEqual(max_age, '')
|
||||
|
|
Loading…
Reference in New Issue