如何在Django中为多个独立域名设置共享登录会话?
Great question—this is a super common pain point when working with independent top-level domains (TLDs) in Django, since the built-in session cookie system is locked to a single domain by default. Let’s walk through the most practical, secure solutions you can implement right now:
1. Build a Custom OAuth2/OpenID Connect (OIDC) Single Sign-On (SSO) System
This is the industry-standard approach for cross-domain authentication, and it’s the most secure and scalable option long-term. Here’s how to set it up:
- Pick one of your domains (say
example1.com) to act as the central authorization server. The other two (example2.comandexample3.com) will be client applications. - Install a Django package like
mozilla-django-oidc(for OIDC, which is built on OAuth2 and tailored for SSO) ordjango-oauth-toolkit(for raw OAuth2). - Configure the authorization server:
- Register
example2.comandexample3.comas trusted clients, with their respective callback URLs (e.g.,https://example2.com/oidc/callback/). - Set up scopes to share necessary user data (like user ID, email) between the server and clients.
- Register
- Configure each client website:
- Add the OIDC settings to
settings.py, including the authorization server’s URL, client ID, and secret. - Update your login views to redirect users to the central authorization server instead of using Django’s default login. Once authenticated, the server will send a token back to the client, which can then create a local session for the user.
- Add the OIDC settings to
- Bonus: You can add single sign-out functionality to invalidate sessions across all domains when a user logs out from one.
2. Shared Session Storage + Cross-Domain JWT Tokens
If you don’t want to implement a full SSO system, this is a simpler alternative that relies on shared session data and secure tokens:
- First, set up a distributed session backend (like Redis) that all three Django projects can access. Update
settings.pyin each project to use the same session engine:SESSION_ENGINE = "django.contrib.sessions.backends.cache" CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://your-redis-server:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } } - When a user logs into one domain (e.g.,
example1.com), generate a JWT token that includes the user’s ID and their session key. Return this token to the frontend. - For the other domains, add a check on page load: if there’s no local session, send a cross-domain AJAX request to
example1.com’s validation endpoint, passing the JWT token. - The validation endpoint on
example1.comwill verify the JWT, check if the session is still valid, and return user data if everything checks out. The client domain can then create a local session using this data. - Critical security notes:
- Enable CORS on all domains to allow cross-origin requests between them (use
django-cors-headerspackage). - Always use HTTPS to prevent token interception.
- Set short expiration times on JWT tokens and refresh them periodically.
- Handle CSRF protection carefully for cross-domain requests—you might need to pass CSRF tokens via headers instead of cookies.
- Enable CORS on all domains to allow cross-origin requests between them (use
3. iframe + postMessage Workaround (Not Recommended for Production)
If you need a quick, temporary fix (and can tolerate higher security risks), you can use browser postMessage and hidden iframes to share session data:
- Embed a hidden iframe from your central domain (e.g.,
example1.com) on every page ofexample2.comandexample3.com. - When a user logs into
example1.com, the iframe can send session details to the parent page usingwindow.postMessage(). - The parent page (on
example2.comorexample3.com) listens for this message and creates a local session using the received data. - Why this is risky: It’s vulnerable to XSS attacks, modern browser privacy features (like SameSite cookie policies) can block this behavior, and it’s hard to maintain long-term.
Final Recommendation
Go with the OIDC/SSO approach if you can—it’s the most secure, maintainable solution that aligns with web security best practices. The shared session + JWT method works for smaller setups, but make sure you lock down the security details.
内容的提问来源于stack exchange,提问作者Nipun Garg

