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

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

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

【问题讨论】:

    标签: django session cookies


    【解决方案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 名称是一个巧妙的技巧,在这种情况下可以使用。感谢您指出!
    猜你喜欢
    • 2010-11-25
    • 2013-01-02
    • 2022-05-12
    • 2012-05-23
    • 2017-07-15
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多