我们最近将 cookie 域 (settings.SESSION_COOKIE_DOMAIN) 从domain.com更改为.domain.com,这会阻止 Safari 用户登录,除非他们清除 cookie。问题的根源在于两个域都设置了sessionid cookie。
有没有办法清除或忽略原始域,或者是建议用户清除 cookie 的唯一方法?
修改设置时可能会发生这种情况SESSION_COOKIE_DOMAIN
。(你说SESSION_COOKE_PATH
改变了)。
的文档SESSION_COOKIE_DOMAIN
附带此警告:
SESSION_COOKIE_DOMAIN
在生产站点上更新此设置时要小心。如果您更新此设置以在以前使用标准域 cookie 的站点上启用跨域 cookie,则现有用户 cookie 将设置为旧域。只要这些 cookie 持续存在,这可能会导致他们无法登录。
如果您从以下位置开始,则会发生这种情况:
SESSION_COOKIE_DOMAIN = None
至
SESSION_COOKIE_DOMAIN = '.domain.com'
正如您所说,客户端现在有两个 cookie,它们将在请求期间发送到服务器,两个 cookie 都命名为sessionid
. 当 Django 查看 cookie 时,它只能访问 Python 字典,因此它只能看到一个sessionid
cookie,而不是两个都发送。
我没有对此进行测试,但解决问题的一些想法可能是:
要求用户删除相应的 cookie。根据用户数量和他们的技能水平,这可能不是一个合理的选择。要求他们删除所有 cookie 可能是不可能的。
等待旧 cookie 过期。默认情况下,sessionid
cookie 似乎有 14 天的有效期。一旦旧的会话 cookie 过期,它们将不再随每个请求一起发送,从而允许新的sessionid
cookie 生效。
更改sessionid
cookie 的名称并编写自定义 Django 中间件来处理新旧sessionid
cookie。
我还没有测试最后一点,但是应该可以将 更改SESSION_COOKIE_NAME
为sessionid
. 现在,这将阻止现有登录用户使用他们现有的sessionid
cookie,因此您需要编写一个自定义中间件,该中间件能够处理sessionid
cookie(旧 cookie)和sessionidnew
当前登录 cookie。
像这样的东西会起作用:
from django.utils.importlib import import_module
from django.contrib.sessions import middleware
from django.conf import settings
class MySessionMiddleware(middleware.SessionMiddleware):
def process_request(self, request):
engine = import_module(settings.SESSION_ENGINE)
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
if session_key is None:
# Look for old cookie in request for auth purposes.
session_key = request.COOKIES.get('sessionid', None)
request.session = engine.SessionStore(session_key)
您必须用这个新的中间件替换SessionMiddleware
in settings.py
under 。MIDDLEWARE_CLASSES
例如:更改'django.contrib.sessions.middleware.SessionMiddleware'
为'custommiddleware.MySessionMiddleware'
custommiddleware.py 是具有上述代码的文件并且存在于您的项目根文件夹中的位置(存在 manage.py 文件的位置)
一旦足够的时间过去并且您对所有旧sessionid
cookie 都已过期感到满意,您可以执行相反的操作并更改回使用sessionid
会话的首选 cookie 名称,最终删除可以处理两种不同类型sessionid
cookie的专家代码.