在Django应用中,每个用户只允许单个活动会话
我想限制登录的用户只有一个活动会话,即,如果用户使用新的SessionID登录,则应终止旧会话。 我已经找到了很多帮助: 在这里 and 和>在这里
我实现了中间件解决方案,还有一些额外的检查...
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
,很好...
到目前为止 mod_wsgi),它行不通!
我试图找到有关此信息的任何信息,但是到目前为止还没有运气...
我发现的最接近的是 this ,但这是“相反的”问题……
任何帮助都将不胜感激。
编辑:在删除会话之前,我添加了调试打印... 片段。
[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
错误
的
这是apache 记录不会被删除... ???
我正在运行与与devServer的postgresql实例完全相同...
edit2:事实证明我的代码是故障...当新的session_key中未找到新的session_key ...
这是 失败的...固定代码...尝试..外面现在位于正确的位置
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()
I want to restrict logged-in users to only have one active session, i.e. if the user logs in with a new sessionid, the old session should be terminated.
I found a lot of help on SO already:
here and here
I implemented the middleware solution, with a bit of extra checking...
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
So far, so good... on the Django dev server (manage.py runserver) everything works properly, it kicks the old session...
...but when using Apache ( with mod_wsgi), it doesn't work!
I've tried to find any information about this, but no luck so far...
The closest I have found is this, but it is kind of the 'opposite' problem...
Any help would be much appreciated.
Edit: I added a debug print before deleting the Session...
here's a snippet from Apache's 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
the first two lies are from when I entered with the first session (Firefox)
the last two are from when I entered with the second session (Chromium)
... it turns out that the old Session record does not get deleted... ???
I'm running vs. the exact same PostgreSQL instance as I did with the devserver...
Edit2: It turned out that my code was buggy... it failed when the new Session_key wasn't found in Session...
here's the fixed code... the try..except is now in the correct place
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
确实到处都有很多类似的问题,但这是我的解决方案。
当用户登录时,检查所有活动会话并删除具有相同
user.id
的会话。对于较小的网站,这应该就可以了。There is indeed a lot of similar questions all over the place, but here is my solution.
When a user logins go over all active sessions and remove the ones with the same
user.id
. For smaller websites, this should do just fine.您始终可以使用这种方法,尽管不建议使用这种方法。
在对用户进行身份验证之前,您将在登录()函数中实现上述代码。
当然,只有在您有一个登录()函数方法的情况下,该方法将用户在他的会话中存储用户,如下所示:
如果您使用此方法,请记住在完成后运行服务器之前将所有会话的数据库清空这些更改是因为它会引起密钥lookup错误。
You can always use this approach though not recommended, it works.
You would implement the code above in your login() function right before authenticating the user.
This of course only works if you have a login() function method that stores the USERS username in his session like follows:
If you use this approach just remember to empty your database of all of your sessions before running your server after you've made these changes because it will raise KeyLookUp errors.
我觉得,以某种方式,django.contrib.auth信号可以在这里提供帮助。登录时,使较旧的用户会话无效。
I feel that, somehow, django.contrib.auth signals could help here. On login, invalidate older user sessions.