我们最近将Cookie域名(settings.SESSION_COOKIE_DOMAIN)从 domain.com 更改为 .domain.com ,现在这阻止Safari用户登录,除非他们清除他们的饼干。问题在于为两个域设置了 sessionid cookie这一事实。
有没有办法清除或忽略原始域名,或者是建议用户清除Cookie的唯一方法?
答案 0 :(得分:8)
修改SESSION_COOKIE_DOMAIN
设置时可能会发生这种情况。 (你说SESSION_COOKE_PATH
已经改变了。)
SESSION_COOKIE_DOMAIN
的文档附带此警告:
SESSION_COOKIE_DOMAIN
在生产站点上更新此设置时要小心。如果你 更新此设置以在站点上启用跨域Cookie 以前使用的标准域cookie,现有的用户cookie将是 设置为旧域。这可能导致他们无法登录 只要这些饼干持续存在。
如果你从以下地方出现这种情况:
SESSION_COOKIE_DOMAIN = None
到
SESSION_COOKIE_DOMAIN = '.domain.com'
正如您所说,客户端现在有两个cookie将在请求期间发送到服务器,两个cookie都名为sessionid
。当Django查看cookie时,它只能访问Python字典,所以每次只能看到一个sessionid
cookie而不是两个cookie。
我没有对此进行测试,但解决问题的一些想法可能是:
要求用户删除相应的Cookie。根据用户数量及其技能水平,这可能不是一个合理的选择。要求他们删除所有他们的cookie可能是不可能的。
等待旧Cookie过期。默认情况下,似乎sessionid
cookie的有效期为14天。旧会话Cookie过期后,将不再随每个请求一起发送,从而允许新的sessionid
Cookie生效。
更改sessionid
cookie的名称并编写自定义Django中间件以处理新旧sessionid
Cookie。
我没有测试最后一点,但应该可以将SESSION_COOKIE_NAME
更改为sessionid
以外的其他内容。现在,这将阻止现有登录用户使用其现有的sessionid
cookie,因此您需要编写一个自定义中间件,该中间件能够处理sessionid
个cookie(对于旧cookie)和{{ 1}}当前登录的cookie。
这样的事情会起作用:
sessionidnew
您必须使用此新中间件替换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
中的settings.py
。例如:将MIDDLEWARE_CLASSES
更改为'django.contrib.sessions.middleware.SessionMiddleware'
,其中custommiddleware.py是包含上述代码的文件,并且存在于项目根文件夹中(存在manage.py文件的位置)
一旦经过足够的时间并且您对所有旧的'custommiddleware.MySessionMiddleware'
Cookie已过期感到满意,您可以执行相反的操作并更改回使用sessionid
作为会话的首选Cookie名称,最终删除了可以处理两种不同类型的sessionid
cookie的专业代码。