How to Build a Simple Django SSO with Shared Sessions and Redis

This tutorial walks through creating two Django projects, configuring a shared session store (either a common file or Redis) to achieve single sign‑on across them, and provides full code snippets, settings adjustments, and testing steps to demonstrate seamless login synchronization.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Build a Simple Django SSO with Shared Sessions and Redis

SSO Introduction

Single Sign‑On (SSO) allows a user who has logged into one system to be automatically logged into other related systems, for example logging into QQ Space also logs into other QQ sites.

There are many ways to implement SSO; this article demonstrates a method that shares the session between multiple Django applications by configuring a common session store.

Setting Up the Test Environment

Create two empty Django projects named SSO1 and SSO2, for example with: django-admin startproject sso Each project contains a templates/login.html file. The login page code is:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="login_content">
        <div class="page-header" id="page_header">
            <h1>登录<small>Login</small></h1>
        </div>
        <div id="login_form">
            <form method="post">
                <div class="form-group">
                    <label for="exampleInputEmail1">Email address</label>
                    <input type="input" class="form-control" name="usr" id="exampleInputEmail1" placeholder="username">
                </div>
                <div class="form-group">
                    <label for="exampleInputPassword1">密码</label>
                    <input type="password" class="form-control" name="password" id="exampleInputPassword1" placeholder="密码">
                </div>
                <div id="login_butt">
                    <button type="submit" class="btn btn-default">登录</button>
                    <button type="button" class="btn btn-default" onclick="">注册</button>
                </div>
            </form>
        </div>
    </div>
</body>
</html>

In each project's view.py add login and logout functions:

from django.http import HttpResponse
from django.shortcuts import render, redirect

def login(request):
    if request.method == 'GET':
        if 'usr' in request.session:
            usr = request.session['usr']
            password = request.session['password']
            return HttpResponse("usr:{},password:{},sessionid:{},cookie:{}".format(usr, password, request.session.session_key, request.COOKIES))
        return render(request, 'login.html')
    if request.method == 'POST':
        usr = request.POST['usr']
        password = request.POST['password']
        request.session['usr'] = usr
        request.session['password'] = password
        return HttpResponse("usr:{},password:{},sessionid:{},cookie:{}".format(usr, password, request.session.session_key, request.COOKIES))

def logout(request):
    request.session.clear()
    return redirect('/login')

Add URL patterns in url.py:

from django.contrib import admin
from django.urls import path
from . import view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', view.login),
    path('logout/', view.logout),
]

Comment out the CSRF middleware in settings.py to simplify testing.

Typical settings.py (relevant parts) after modifications:

from pathlib import Path
import os

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = 'o=blc^vzeb1&g*b!si(wtxe44_=i5cv(3jqm2*u2u&7vgj%&=%'
DEBUG = True
ALLOWED_HOSTS = []

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'SSO1.urls'

TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',
            'django.contrib.messages.context_processors.messages',
        ],
    },
}]

WSGI_APPLICATION = 'SSO1.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

STATIC_URL = '/static/'

Run migrations and start each project on different ports:

python3 manage.py migrate
python3 manage.py runserver 127.0.0.1:5000   # SSO1
python3 manage.py runserver 127.0.0.1:7000   # SSO2

Open http://127.0.0.1:5000/login/ and http://127.0.0.1:7000/login/ in a browser; both show the login page.

Two Ways to Share Sessions

Store the session in the same file on the filesystem.

Store the session in Redis.

File‑Based Session Sharing

Create a directory that both projects can access and configure the same session store:

# Set cookie domain to the parent domain (here using localhost)
SESSION_COOKIE_DOMAIN = '127.0.0.1'

# Use file‑based session backend
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# Absolute path to the shared session folder
SESSION_FILE_PATH = '/Users/qiguan/Documents/develop_files/python_files/SSO2/session'

After logging in to http://127.0.0.1:5000/login/ you will see a response such as:

usr:123,password:123,sessionid:2bs2nx2iq879epxu7au7o1zq63o095v7,cookie:{'sessionid': '2bs2nx2iq879epxu7au7o1zq63o095v7', 'csrftoken': '...'}

Visiting http://127.0.0.1:7000/login/ without logging in shows the same user information, confirming that the two applications share the session.

Redis‑Based Session Sharing

Install Redis and the Django‑Redis client:

pip3 install django-redis

Update settings.py to use Redis as the session cache:

# Caches configuration
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100},
            # "PASSWORD": "123",
        },
    }
}

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 60 * 5

After clearing the session via the logout view, logging in on one port again produces a response with a new session ID, and the other port instantly reflects the same logged‑in user, demonstrating successful SSO with Redis.

This guide provides a basic, functional SSO implementation for Django projects; you can adapt the configuration to suit more complex production requirements.

Original source: https://qiguanjie.blog.csdn.net/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendredisDjangoSSOSession
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.