You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django跨域会话共享咨询:实现abc.com与xyz.com会话互通

嘿,这个跨域名会话共享的需求我刚好在项目里踩过坑,在Django框架下实现得先区分你的域名类型——是同一顶级域的子域名,还是完全独立的顶级域?两种场景的实现方式差异很大,下面分别给你讲清楚:

场景一:abc.com和xyz.com是同一顶级域的子域名(比如实际是abc.example.com和xyz.example.com)

这种情况可以直接通过Cookie配置+共享会话存储来实现:

1. 配置共享的会话存储

默认的Django数据库会话存储(django.contrib.sessions.backends.db)就可以用,但如果是分布式部署,更推荐用Redis/Memcached这类分布式存储,确保两个站点能访问同一份会话数据。比如用Redis:
先装依赖:

pip install django-redis

然后在两个站点的settings.py里统一配置:

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://你的-redis地址:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

如果用数据库存储,确保两个站点连接同一个数据库,能访问django_session表。

2. 配置Cookie跨域参数

在两个站点的settings.py里添加:

# 允许所有子域共享Cookie,注意前面的点
SESSION_COOKIE_DOMAIN = ".example.com"
# 允许跨域发送Cookie,必须配合HTTPS
SESSION_COOKIE_SAMESITE = "None"
# 生产环境必须开启HTTPS,否则浏览器会拒绝SameSite=None的Cookie
SESSION_COOKIE_SECURE = True
# 统一Cookie名称,默认是sessionid,不用改的话可以忽略
SESSION_COOKIE_NAME = "sessionid"

3. 统一核心配置

两个站点的SECRET_KEY必须完全一致,因为Django用它加密会话数据,不一致的话无法解密对方的会话。

场景二:abc.com和xyz.com是完全独立的顶级域

这种情况浏览器的同源策略会直接阻止跨域共享Cookie,必须用**单点登录(SSO)**方案,这里给你推荐基于Django的落地方式:

1. 选一个站点作为认证中心(比如abc.com)

在abc.com上安装django-oauth-toolkit来实现OAuth2认证:

pip install django-oauth-toolkit

然后配置settings.py:

INSTALLED_APPS = [
    # ...其他应用
    'oauth2_provider',
]

MIDDLEWARE = [
    # ...其他中间件
    'oauth2_provider.middleware.OAuth2TokenMiddleware',
]

AUTHENTICATION_BACKENDS = [
    'oauth2_provider.backends.OAuth2Backend',
    'django.contrib.auth.backends.ModelBackend',
]

OAUTH2_PROVIDER = {
    'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'},
    'ACCESS_TOKEN_EXPIRE_SECONDS': 3600,  # 令牌有效期
}

然后在urls.py里添加OAuth2的路由:

from django.urls import path, include
from oauth2_provider.views import AuthorizationView, TokenView, RevokeTokenView

urlpatterns = [
    # ...其他路由
    path('oauth2/', include('oauth2_provider.urls', namespace='oauth2_provider')),
]

2. 在xyz.com上配置OAuth2客户端

安装requests-oauthlib:

pip install requests-oauthlib

然后在xyz.com的settings.py里添加认证中心的配置:

OAUTH2_CLIENT_ID = "你的abc.com上创建的客户端ID"
OAUTH2_CLIENT_SECRET = "你的客户端密钥"
OAUTH2_AUTHORIZE_URL = "https://abc.com/oauth2/authorize/"
OAUTH2_TOKEN_URL = "https://abc.com/oauth2/token/"
OAUTH2_USERINFO_URL = "https://abc.com/api/userinfo/"  # 你需要在abc.com写一个接口返回用户信息

然后写一个视图来处理跳转认证和获取用户信息:

from django.shortcuts import redirect
from django.contrib.auth import login
from requests_oauthlib import OAuth2Session

def sso_login(request):
    oauth = OAuth2Session(OAUTH2_CLIENT_ID, redirect_uri="https://xyz.com/sso/callback/")
    authorization_url, state = oauth.authorization_url(OAUTH2_AUTHORIZE_URL)
    request.session['oauth_state'] = state
    return redirect(authorization_url)

def sso_callback(request):
    oauth = OAuth2Session(OAUTH2_CLIENT_ID, state=request.session['oauth_state'], redirect_uri="https://xyz.com/sso/callback/")
    token = oauth.fetch_token(OAUTH2_TOKEN_URL, client_secret=OAUTH2_CLIENT_SECRET, authorization_response=request.build_absolute_uri())
    user_info = oauth.get(OAUTH2_USERINFO_URL).json()
    
    # 根据user_info创建或获取本地用户
    from django.contrib.auth.models import User
    user, created = User.objects.get_or_create(username=user_info['username'], defaults={'email': user_info['email']})
    login(request, user)
    return redirect('/')

在xyz.com的urls.py里添加这两个视图的路由。

3. 测试流程

  1. 用户访问xyz.com,未登录则跳转到abc.com的认证页面;
  2. 用户在abc.com登录后,授权xyz.com访问用户信息;
  3. 跳转回xyz.com,自动创建本地会话,实现登录状态共享。
通用注意事项
  • 生产环境必须开启HTTPS,否则跨域Cookie和OAuth2都无法正常工作;
  • 两个站点的用户模型最好保持一致,避免用户信息同步出现问题;
  • 如果用SSO方案,要做好令牌的过期和刷新机制。

内容的提问来源于stack exchange,提问作者Neha Goel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:59:02