Skip to content

Authorization & Sessions

Django's authentication system relies on sessions to track logged-in users and a permissions framework to authorize their actions.

Sessions

Sessions store user state across HTTP requests using a cookie and a server-side backend.

  • Configuration: Enabled by default via django.contrib.sessions in INSTALLED_APPS and SessionMiddleware in MIDDLEWARE.

  • Usage: Access data via request.session, which behaves like a dictionary.

    python
    request.session["theme"] = "dark"
    
    # Mark as modified if mutating nested data:
    request.session["cart"].append("apple")
    request.session.modified = True
  • Backends (SESSION_ENGINE):

    • ...backends.db: Default. Durable, requires a DB query per request.
    • ...backends.cached_db: Recommended for production. Fast reads via cache, durable writes to DB.
    • ...backends.cache: Fastest, but volatile (sessions clear on cache restart/eviction).
    • ...backends.signed_cookies: Client-side. Fast, but exposes data and cannot be explicitly revoked by the server.
  • Security: Set SESSION_COOKIE_SECURE = True and SESSION_COOKIE_HTTPONLY = True in production.

Permissions

Authorization determines what an authenticated user may do. Permissions can be attached to any model.

  • Default Permissions: Running migrate creates add, change, delete, and view permissions for every model (e.g., blog.add_article).

  • Superusers (is_superuser=True) implicitly hold all permissions. Inactive users hold none.

  • Checking Permissions:

    python
    user.has_perm("blog.add_article")
  • Protecting Views:

    python
    from django.contrib.auth.decorators import permission_required
    
    @permission_required("blog.change_article", raise_exception=True)
    def edit_article(request, pk):
        ...
  • Custom Permissions: Define them in a model's Meta class:

    python
    class Article(models.Model):
        class Meta:
            permissions = [("publish_article", "Can publish an article")]

Groups & Object-Level Access

  • Groups: A Group is a named bucket of permissions (e.g., "Editors"). Users inherit all permissions assigned to their groups.

    python
    from django.contrib.auth.models import Group
    editors = Group.objects.get(name="Editors")
    user.groups.add(editors)
  • Object-Level Permissions: Django's default backends apply permissions model-wide, ignoring per-object checks. To enforce rules like "users can only edit their own articles", either write a custom backend or use a third-party package like django-guardian.