django 会话密钥在身份验证时更改

Posted

技术标签:

【中文标题】django 会话密钥在身份验证时更改【英文标题】:django session key changing upon authentication 【发布时间】:2012-12-08 08:47:11 【问题描述】:

我有一个 Django 应用程序,它记录用户对两个经过身份验证的用户的产品选择。如果用户决定稍后注册,我的意图是使用 request.session.session_key 变量将匿名数据与用户相关联,例如这篇文章:

Django storing anonymous user data

但是,似乎会话密钥在用户登录/注册时发生了变化,因此会话密钥无法再与用户关联。这是 Django 会话框架的正确行为吗?是否有可靠的方法来实现我正在寻找的功能?

非常感谢任何帮助。

【问题讨论】:

看看Django sessions: changing session key when modified。 请注意,会话密钥的这种更改在一定程度上有助于防止会话固定。所以在关闭它之前考虑一下。 【参考方案1】:

在settings.py中

SESSION_ENGINE = 'youapp.session_backend'

在文件 session_backend.py 中的目录 youapp 中

from django.contrib.sessions.backends.db import SessionStore as DbSessionStore

class SessionStore(DbSessionStore):
    def cycle_key(self):
        pass

登录后会话没有改变

【讨论】:

这对我有用,但我无法确认它是否完全安全。我正在使用字符串匹配在登录跳转时加入 session_key。【参考方案2】:

虽然 nnmware 建议的方法可能适用于这种特殊情况,但还有更好的方法。

我们应该调用 super 方法然后保存会话,而不是在 cycle_key 中什么都不做。

因为如果您查看原始 cycle_key 函数内部,您会看到旧会话中的数据被复制到新会话中,但实际上并未保存。

在settings.py中

SESSION_ENGINE = 'yourapp.session_backend'

检查 SESSION_ENGINE 是否指向模块(.py 文件),而不是后端类!

现在,在您的“yourapp/session_backend.py”中执行以下操作:

from django.contrib.sessions.backends.db import SessionStore as DbSessionStore

class SessionStore(DbSessionStore):
    def cycle_key(self):
        super(SessionStore, self).cycle_key()
        self.save()

【讨论】:

我不太确定这是否更好,取决于您是否依赖旧会话中的信息(它是直接引用它的对象,或者它是关键),在这种情况下,您需要旧的以保持一致,因此您可以将其绑定到登录事件之前跟踪的记录。对我来说,只是停止循环就可以了,希望不会造成问题。【参考方案3】:

其中一种解决方案也是更新会话存储中的旧会话数据:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.contrib.sessions.backends.db import SessionStore as DbSessionStore
from shop.models.cart import Cart


class SessionStore(DbSessionStore):
    def cycle_key(self):
        old_session_key = super(SessionStore, self).session_key
        super(SessionStore, self).cycle_key()
        self.save()
        Cart.objects.filter(session_key=old_session_key).update(session_key=self.session_key)

【讨论】:

以上是关于django 会话密钥在身份验证时更改的主要内容,如果未能解决你的问题,请参考以下文章

Django 如何在第一次迁移时制作与用户、身份验证、组、会话等相关的表?

维护用户会话而无需将用户保存在 django 身份验证系统中

使用 Django 通道进行会话身份验证

Django - 当页面不存在或用户未通过身份验证时返回更改答案

Phonegap 和 Django 身份验证

Django,Djoser 社交身份验证:在服务器端会话数据中找不到状态。状态码 400