SessionMiddleware is activated, each
HttpRequest object – the first argument to any Django view function – will have a
session attribute, which is a dictionary-like object. You can read it and write to
request.session at any point in your view. You can also edit it multiple times.
All session objects inherit from the base class
backends.base.SessionBase. It has the following standard dictionary methods:
It also has these methods:
Delete the current session data from the session and delete the session cookie. This is used if you want to ensure that the previous session data can’t be accessed again from the user’s browser (for example, the
django.contrib.auth.logout() function calls it).
Sets a test cookie to determine whether the user’s browser supports cookies. Due to the way cookies work, you won’t be able to test this until the user’s next page request. See “setting test cookies”
below for more information.
False, depending on whether the user’s browser accepted the test cookie. Due to the way cookies work, you’ll have to call
set_test_cookie() on a previous, separate page request. See “Setting test cookies” below for more information.
Deletes the test cookie. Use this to clean up after yourself.
Sets the expiration time for the session. You can pass a number of different values:
valueis an integer, the session will expire after that many seconds of inactivity.
For example, calling
request.session.set_expiry(300)would make the session expire in 5 minutes.
timedeltaobject, the session will expire at that specific date/time. Note that
timedeltavalues are only serializable if you are using the
0, the user’s session cookie will expire when the user’s Web browser is closed.
None, the session reverts to using the global session expiry policy.
Reading a session is not considered activity for expiration purposes. Session expiration is computed from the last time the session was modified.
Returns the number of seconds until this session expires. For sessions with no custom expiration (or those set to expire at browser close), this will equal
SESSION_COOKIE_AGE. This function accepts two optional keyword arguments:
modification: last modification of the session, as a
datetimeobject. Defaults to the current time.
expiry: expiry information for the session, as a
int(in seconds), or
None. Defaults to the value stored in the session by
set_expiry(), if there is one, or
Returns the date this session will expire. For sessions with no custom expiration (or those set to expire at browser close), this will equal the date
SESSION_COOKIE_AGE seconds from now. This function accepts the same keyword arguments as
False, depending on whether the user’s session cookie will expire when the user’s Web browser is closed.
Removes expired sessions from the session store. This class method is called by
Creates a new session key while retaining the current session data.
django.contrib.auth.login() calls this method to mitigate against session fixation.
Session Object Guidelines
- Use normal Python strings as dictionary keys on
request.session. This is more of a convention than a hard-and-fast rule.
- Session dictionary keys that begin with an underscore are reserved for internal use by Django.
- Don’t override
request.sessionwith a new object, and don’t access or set its attributes. Use it like a Python dictionary.
Before version 1.6, Django defaulted to using
pickle to serialize session data before storing it in the backend. If you’re using the signed cookie session backend and
SECRET_KEY is known by an attacker (there isn’t an inherent vulnerability in Django that would cause it to leak), the attacker could insert a string into their session which, when unpickled, executes arbitrary code on the server. The technique for doing so is simple and easily available on the internet.
Although the cookie session storage signs the cookie-stored data to prevent tampering, a
SECRET_KEY leak immediately escalates to a remote code execution vulnerability. This attack can be mitigated by serializing session data using JSON rather than
pickle. To facilitate this, Django 1.5.3 introduced a new setting,
SESSION_SERIALIZER, to customize the session serialization format. For backwards compatibility, this setting defaults to using
django.contrib.sessions.serializers.PickleSerializer in Django 1.5.x, but, for security hardening, defaults to
django.contrib.sessions.serializers.JSONSerializer from Django 1.6 onward.
Even with the caveats described in custom-serializers, we highly recommend sticking with JSON serialization especially if you are using the cookie backend.
A wrapper around the JSON serializer from
django.core.signing. Can only serialize basic data types. In addition, as JSON supports only string keys, note that using non-string keys in
request.session won’t work as expected:
See the custom-serializers section for more details on limitations of JSON serialization.
Supports arbitrary Python objects, but, as described above, can lead to a remote code execution vulnerability if
SECRET_KEY becomes known by an attacker.
Write Your Own Serializer
Note that unlike
JSONSerializer cannot handle arbitrary Python data types. As is often the case, there is a trade-off between convenience and security. If you wish to store more advanced data types including
Decimal in JSON backed sessions, you will need to write a custom serializer (or convert such values to a JSON serializable object before storing them in
While serializing these values is fairly straightforward (
django.core.serializers.json.DateTimeAwareJSONEncoder may be helpful), writing a decoder that can reliably get back the same thing that you put in is more fragile. For example, you run the risk of returning a
datetime that was actually a string that just happened to be in the same format chosen for
Your serializer class must implement two methods,
dumps(self, obj) and
loads(self, data), to serialize and deserialize the dictionary of session data, respectively.
Setting Test Cookies
As a convenience, Django provides an easy way to test whether the user’s browser accepts cookies. Just call the
set_test_cookie() method of
request.session in a view, and call
test_cookie_worked() in a subsequent view – not in the same view call.
This awkward split between
test_cookie_worked() is necessary due to the way cookies work. When you set a cookie, you can’t actually tell whether a browser accepted it until the browser’s next request. It’s good practice to use
delete_test_cookie() to clean up after yourself. Do this after you’ve verified that the test cookie worked.
Here’s a typical usage example: