【发布时间】:2012-02-14 04:29:36
【问题描述】:
我想限制登录用户只有一个活动会话,即如果用户使用新的 sessionid 登录,旧的会话应该被终止。 我已经在 SO 上找到了很多帮助: here 和 here
我实现了中间件解决方案,并进行了一些额外的检查...
class OnlyOneUserMiddleware(object):
"""
Middleware to ensure that a logged-in user only has one session active.
Will kick out any previous session.
"""
def process_request(self, request):
if request.user.is_authenticated():
try:
cur_session_key = request.user.get_profile().session_key
if cur_session_key and cur_session_key != request.session.session_key:
# Default handling... kick the old session...
Session.objects.get(session_key=cur_session_key).delete()
if not cur_session_key or cur_session_key != request.session.session_key:
p = request.user.get_profile()
p.session_key = request.session.session_key
p.save()
except ObjectDoesNotExist:
pass
到目前为止,一切都很好......在 Django 开发服务器(manage.py runserver)上一切正常,它踢掉了旧会话......
...但是当使用 Apache (with mod_wsgi) 时,它不起作用!
我试图找到有关此的任何信息,但到目前为止还没有运气......
我找到的最接近的是this,但这是一种“相反”的问题......
任何帮助将不胜感激。
编辑:我在删除会话之前添加了一个调试打印... 这是来自 Apache 的 error.log 的 sn-p:
[Fri Jan 20 09:56:50 2012] [error] old key = f42885ccb7f33b6afcb2c18fca14f44a
[Fri Jan 20 09:56:50 2012] [error] new key = ce4cfb672e6025edb8ffcd0cf2b4b8d1
[Fri Jan 20 09:57:14 2012] [error] old key = f42885ccb7f33b6afcb2c18fca14f44a
[Fri Jan 20 09:57:14 2012] [error] new key = 0815c56241ac21cf4b14b326f0aa7e24
前两个谎言来自我使用第一个会话(Firefox)进入时
最后两个是从我进入第二个会话(Chromium)时开始的
...原来旧的Session记录没有被删除...???
我正在运行与使用 devserver 完全相同的 PostgreSQL 实例...
Edit2:原来我的代码有问题......当在 Session 中找不到新的 Session_key 时它失败了......
这里是固定代码... try..except 现在在正确的位置
class OnlyOneUserMiddleware(object):
"""
Middleware to ensure that a logged-in user only has one session active.
Will kick out any previous session.
"""
def process_request(self, request):
if request.user.is_authenticated():
cur_session_key = request.user.get_profile().session_key
if cur_session_key and cur_session_key != request.session.session_key:
# Default handling... kick the old session...
try:
s = Session.objects.get(session_key=cur_session_key)
s.delete()
except ObjectDoesNotExist:
pass
if not cur_session_key or cur_session_key != request.session.session_key:
p = request.user.get_profile()
p.session_key = request.session.session_key
p.save()
【问题讨论】:
-
当您说“不起作用”时,究竟是什么不起作用?您还在数据库中看到旧会话吗?如果您在
Session删除之前进行打印/记录调用,您是否看到在mod_wsgi下执行? -
@AdamKG:感谢您为我指明正确的方向!
-
如果会话引擎是cache_db,我想我们也需要手动从缓存中移除sessionkey吧?
-
user.get_profile()是做什么的?
标签: python django apache2 mod-wsgi django-authentication