Mar*_*son 23 python django mod-wsgi apache2 django-authentication
我想限制登录用户只有一个活动会话,即如果用户使用新的sessionid登录,则应终止旧会话.我已经在SO上找到了很多帮助: 这里和这里
我实现了中间件解决方案,还有一些额外的检查......
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
Run Code Online (Sandbox Code Playgroud)
到目前为止,这么好......在Django开发服务器(manage.py runserver)上一切正常,它踢旧会话......
...但是当使用Apache(使用mod_wsgi)时,它不起作用!
我试图找到关于此的任何信息,但到目前为止没有运气......
我发现的最接近的是这个,但它是一种"相反"的问题......
任何帮助将非常感激.
编辑:我在删除Session之前添加了一个调试打印...这是Apache的error.log的一个片段:
[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
Run Code Online (Sandbox Code Playgroud)
前两个谎言是从我第一次进入第一个会话(Firefox)
最后两个是从我第二次参加会议时开始的(Chromium)
...事实证明旧的Session记录没有被删除...... ???
我正在运行与完全相同的PostgreSQL实例,就像我使用devserver一样...
编辑2:事实证明我的代码是错误的......当在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()
Run Code Online (Sandbox Code Playgroud)
小智 1
尽管不推荐,您始终可以使用此方法,但它确实有效。
my_old_sessions = Session.objects.all()
for row in my_old_sessions:
if row.get_decoded().get("_username") == request.user.username:
row.delete()
Run Code Online (Sandbox Code Playgroud)
在对用户进行身份验证之前,您可以在 login() 函数中实现上面的代码。
当然,只有当您有一个在会话中存储 USERS 用户名的 login() 函数方法时,这才有效,如下所示:
request.session["_username"] = request.user.username
Run Code Online (Sandbox Code Playgroud)
如果您使用此方法,请记住在进行这些更改后运行服务器之前清空所有会话的数据库,因为这会引发 KeyLookUp 错误。
| 归档时间: |
|
| 查看次数: |
4239 次 |
| 最近记录: |