about 2 years ago

When a user request a page view from a website (powered by Django), a cookie is returned along with the requested page. Inside this cookie, a key/value pair is presented:

Cookie on the user's computer

Key          Value
---          -----
sessionid    gilg56nsdelont4740onjyto48sv2h7l

This id is used to uniquely identify who's who by the server. User A's id is different from User B's etc. This id is not only stored in the cookie on the user's computer, it is also stored in the database on the server (assuming you are using the default session engine). By default, after running ./manage.py migrate, a table named django_session is created in the database. It has three columns:

django_session table in database

session_key        session_data        expire_date
y5j0jy3l4v3        ZTJlMmZiMGYw        2015-05-08 15:13:28.226903

The value stored in the session_key column matches the value stored in the cookie received by the user.

Let's say this user decides to login to the web service. Upon successfully logged into the system, a new sessionid is assigned to him/her and a different session_data is stored in the database:

Before logging in:

session_key        session_data        expire_date
437383928373        anonymous           2015-05-08 15:13:28.226903
After logging in:

session_key        session_data        expire_date
218374758493        John               2015-05-08 15:13:28.226903

*I made up this example to use numbers and usernames instead of hash strings. For security reasons, these are all hash strings in reality.

As we can see here, a new session_key has been assigned to this user and we now know that this user is 'John'. Form now on, John's session_key will not change even if he closes the browser and visit this server again. Thus, when John comes back the next day, he does not need to login again.

Django provides a setting to let developers to specify this behaviour, in settings.py, a variable named SESSION_SAVE_EVERY_REQUEST can be set:

SESSION_EXPIRE_AT_BROWSER_CLOSE = False # this is the default value. the session_id will not expire until SESSION_COOKIE_AGE has reached.

If this is set to True, then John is forced to login everytime he visits this website.

Since saving and retrieving session data from the database can be slow, we can store session data in memory by:

#Assuming memcached is installed and set as the default cache engine
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'

The advantage of this approach is that session store/retrival will be faster. But the downside is if the server crashes, all session data is lost.

A mix of cache & database storage is:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

According to django's documentation:

every write to the cache will also be written to the database. Session reads only use the database if the data is not already in the cache.

This approach is slower than a pure cache solution but faster than a purse db solution.

Django's offical document did warn to not use local-memory cache as it doesn't retain data long enough to be a good choice.

By default the session data for a logged in user lasts two weeks in Django, users have to log back in after the session expires. This time period can be adjusted by setting the SESSION_COOKIE_AGE variable.

← Install Python on CentOS 6.5 Django login users without password →
comments powered by Disqus