如何在 Django 中清除旧 SESSION_COOKIE_DOMAIN 的 cookie

Posted

技术标签:

【中文标题】如何在 Django 中清除旧 SESSION_COOKIE_DOMAIN 的 cookie【英文标题】:How to clear cookies for old SESSION_COOKIE_DOMAIN in Django 【发布时间】:2013-03-15 13:40:10 【问题描述】:

我们最近将 cookie 域 (settings.SESSION_COOKIE_DOMAIN) 从 domain.com 更改为 .domain.com,这会阻止 Safari 用户登录,除非他们清除他们的饼干。问题的根源在于两个域都设置了 sessionid cookie。

有没有办法清除或忽略原始域,或者是建议用户清除 cookie 的唯一方法?

【问题讨论】:

【参考方案1】:

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)

您必须将settings.py 中的SessionMiddleware 替换为MIDDLEWARE_CLASSES 下的这个新中间件。例如:将 'django.contrib.sessions.middleware.SessionMiddleware' 更改为 'custommiddleware.MySessionMiddleware' 其中 custommiddleware.py 是包含上述代码的文件,并且存在于您的项目根文件夹中(其中存在 manage.py 文件)

一旦经过足够的时间并且您对所有旧的 sessionid cookie 都已过期感到满意,您可以执行相反的操作并改回使用 sessionid 作为会话的首选 cookie 名称,最终删除专家可以处理两种不同类型的sessionid cookie 的代码。

【讨论】:

是的,我的意思是SESSION_COOKIE_DOMAIN,错误输入为SESSION_COOKIE_PATH。更改会话 cookie 名称是一个巧妙的技巧,在这种情况下可以使用。感谢您指出!

以上是关于如何在 Django 中清除旧 SESSION_COOKIE_DOMAIN 的 cookie的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js / webpack:当热重载编译它们时,如何清除旧的包 main-*.js 文件?

如何在restkit映射后和保存到实体之前清除旧实体?

如何从 MySQL 数据库表中清除旧条目?

在 Django 中,如何清除 sessionkey?

如何使用 CGContext 方法清除旧数据的绘制?

如何从 Maven 存储库中清除旧的依赖项?