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 身份验证系统中