Django sessions

About Session

  • A session is a way to store information about a user across multiple HTTP requests.
  • HTTP is a stateless protocol, meaning each request is independent of others.
  • Sessions bridge this gap by preserving state information, such as user authentication status, cart details, or preferences.

Django Session Framework

  • Django's session framework allows developers to store and retrieve arbitrary data on a per-site-visitor basis.
  • The data is stored on the server side, and a session ID is stored in the client's browser as a cookie.
  • Alternatively, the session ID can be passed as part of the URL (though this is rarely used).

Session Storage Backends

Django supports several session storage backends. The choice of backend depends on the requirements of your project:

  1. Database-backed sessions (default): Stores session data in the database.
  2. File-based sessions: Stores session data in the file system.
  3. Cached sessions: Stores session data in the cache.
  4. Cached database sessions: Stores session data in the database and uses cache as a fallback.
  5. Cookie-based sessions: Stores session data directly in a secure cookie.

Configuring session backend

settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # Default: database
# Other options include:
# 'django.contrib.sessions.backends.file'
# 'django.contrib.sessions.backends.cache'
# 'django.contrib.sessions.backends.cached_db'
# 'django.contrib.sessions.backends.signed_cookies'

Enabling Sessions

  • Django’s session framework is included in the default settings of a Django project.
  • Ensure the following are included in INSTALLED_APPS:

settings.py

INSTALLED_APPS = [
    'django.contrib.sessions',
    ...
]

MIDDLEWARE = [
    ...
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...
]
  • Run the command python manage.py migrate to create the necessary database table for storing session data (if using the default backend)

Setting Session Data

  • We can store data in the session object as key-value pairs. Here’s an example:
from django.shortcuts import render

def set_session(request):
    request.session['username'] = 'john_doe'
    request.session['email'] = '[email protected]'
    return render(request, 'set_session.html', {'message': 'Session data set!'})

Retrieving Session Data

  • To retrieve session data, use the request.session dictionary
from django.shortcuts import render

def get_session(request):
    username = request.session.get('username', 'Guest')
    email = request.session.get('email', 'Not provided')
    return render(request, 'get_session.html', {'username': username, 'email': email})

note: The .get() method ensures that the session doesn’t throw a KeyError if the key doesn’t exist.

Deleting Session Data

  • We can delete individual session keys or clear the entire session
from django.shortcuts import render

def delete_session(request):
    if 'username' in request.session:
        del request.session['username']  # Deletes a single key
    request.session.flush()  # Clears all session data and deletes the session cookie
    return render(request, 'delete_session.html', {'message': 'Session cleared!'})

Session Expiry

  • Django allows setting custom session expiration policies.
  • You can set the session to expire after a specified time or close the browser

Setting Session Timeout

SESSION_COOKIE_AGE = 3600

Expiring Session on Browser Close

SESSION_EXPIRE_AT_BROWSER_CLOSE = True

Custom Expiry for Specific Sessions

request.session.set_expiry(300)  # Session expires after 5 minutes

Checking Session Status

if request.session.get('username'):
    print("Session exists!")

Checking Session Status

if request.session.get('username'):
    print("Session exists!")
  • You can also check if a session is new
if request.session.is_empty():
    print("No session data.")

Securing Sessions

To enhance session security:

  1. Use HTTPS: Ensure that cookies are transmitted securely by enabling HTTPS.
  2. Secure Session Cookies: Use SESSION_COOKIE_SECURE to transmit cookies only over HTTPS.
  3. HttpOnly Cookies: Prevent JavaScript access to session cookies using SESSION_COOKIE_HTTPONLY.
  4. Set SameSite Attribute: Restrict cookies to same-site requests using SESSION_COOKIE_SAMESITE.
# settings.py
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'

Example Application: User Login Session

  • Below is an example of a simple login system that uses Django sessions:

views.py

from django.shortcuts import render, redirect

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # Dummy authentication for demonstration
        if username == 'admin' and password == 'password123':
            request.session['username'] = username
            return redirect('dashboard')
        return render(request, 'login.html', {'error': 'Invalid credentials'})
    return render(request, 'login.html')

def dashboard(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')
    return render(request, 'dashboard.html', {'username': username})

def logout(request):
    request.session.flush()  # Clear session data
    return redirect('login')

templates.py

<form method="POST">
    {% csrf_token %}
    <input type="text" name="username" placeholder="Username" required>
    <input type="password" name="password" placeholder="Password" required>
    <button type="submit">Login</button>
    {% if error %}
        <p style="color:red;">{{ error }}</p>
    {% endif %}
</form>

dashboard.html

<h1>Welcome, {{ username }}</h1>
<a href="{% url 'logout' %}">Logout</a>

References: