Django多租户:公共Schema登录重定向子域名主页遇Session错误
解决跨子域名登录共享及SessionInterrupted错误
一、先搞定跨子域名会话共享的核心配置
要让logic.com和tenant1.logic.com共享登录状态,关键是让Session Cookie能被所有子域名识别:
- 在
settings.py里设置SESSION_COOKIE_DOMAIN = '.logic.com'(注意开头的点,这是让所有子域名都能读取该Cookie的关键) - 如果站点用HTTPS,必须开启
SESSION_COOKIE_SECURE = True,否则浏览器会因为安全策略拒绝跨子域名传递Cookie - 确认
SESSION_ENGINE用默认的django.contrib.sessions.backends.db或者缓存后端,别用文件型引擎,这类引擎不支持跨域共享
二、修复SessionInterrupted错误
这个错误本质是请求处理过程中Session被意外删除了,结合你的场景,大概率是登录视图逻辑有问题:
- 检查login_user视图的操作
- 登录逻辑里别随便调用
request.session.flush()或request.session.clear(),这些操作会直接删除/清空Session,只有登出时才用得到 - 登录成功后只需要调用
auth.login(request, user)就行,别画蛇添足去修改Session - 给你个正确的视图示例:
from django.contrib.auth import authenticate, login from django.shortcuts import redirect, render def login_user(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') user = authenticate(request, username=username, password=password) if user: login(request, user) # 直接重定向到子域名主页 return redirect('https://tenant1.logic.com') # 登录失败的处理 else: return render(request, 'login.html', {'error': '用户名或密码错误'}) return render(request, 'login.html')
- 登录逻辑里别随便调用
- 排查并发请求问题
- 登录过程中别触发其他并发请求(比如前端自动刷新、异步接口调用),这类请求可能会意外修改或删除Session
- 如果用AJAX做登录,要确保登录请求完成前,页面没有其他操作Session的请求
- 核对中间件顺序
- 在
settings.py的MIDDLEWARE里,SessionMiddleware必须在AuthenticationMiddleware前面,顺序错了会导致Session处理异常:MIDDLEWARE = [ # 其他中间件 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 其他中间件 ]
- 在
三、验证配置是否生效
- 登录
logic.com后,打开浏览器开发者工具(F12),查看Cookie列表,确认sessionid的Domain是.logic.com,Path为/ - 访问
tenant1.logic.com,检查请求头里是否带了这个sessionidCookie,后端用request.user.is_authenticated就能判断用户是否已登录
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

