允许每个用户只单个活动会议Django应用程序 [英] Allowing only single active session per user in Django app

查看:115
本文介绍了允许每个用户只单个活动会议Django应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想限制登录的用户只能有一个活动会话,即,如果用新的SessionID用户登录,旧会话应被终止。
我发现了很多的帮助,对SO早已:
<一href=\"http://stackoverflow.com/questions/1814437/allow-only-one-concurrent-login-per-user-in-django-app\">here和<一个href=\"http://stackoverflow.com/questions/821870/how-can-i-detect-multiple-logins-into-a-django-web-application-from-different-lo\">here

我实现了中间件解决方案,具有一些额外检查的...

 类OnlyOneUserMiddleware(对象):

中间件以确保一个登录用户仅具有活跃的一个会话。
会踢任何previous会话。

高清process_request(个体经营,要求):
    如果request.user.is_authenticated():
        尝试:
            cur_session_key = request.user.get_profile()。session_key可以
            如果cur_session_key和cur_session_key = request.session.session_key!
                #默认处理......踢旧的会话...
                Session.objects.get(session_key可以= cur_session_key).delete()
            如果不是cur_session_key或cur_session_key = request.session.session_key!
                P = request.user.get_profile()
                p.session_key = request.session.session_key
                p.save()
        除了ObjectDoesNotExist:
            通过

到目前为止,一切都很好... Django的开发服务器上(manage.py的runserver)一切正常,它踢旧的会话...

...但使用Apache(与mod_wsgi的)的时候,这是行不通的!

我一直试图找到这方面有任何信息,但至今没有运气...

我发现的最接近的是这个,但它是一种的相反的问题...

任何帮助将是非常美联社preciated。

编辑:我删除会议之前增加了一个调试打印...
这里是来自Apache的error.log中的一个片段:

  [周五1月20日9时56分五十零秒2012] [错误]旧钥匙= f42885ccb7f33b6afcb2c18fca14f44a
[周五1月20日九时56分50秒2012] [错误]新的关键= ce4cfb672e6025edb8ffcd0cf2b4b8d1
[周五1月20日九点57分14秒2012] [错误]旧钥匙= f42885ccb7f33b6afcb2c18fca14f44a
[周五1月20日九点57分14秒2012] [错误]新的关键= 0815c56241ac21cf4b14b326f0aa7e24

前两个谎言都是从我的第一次会议(火狐)签订

最后两个来自当我第二次会议(铬)进入

......事实证明,旧的会话记录不被删除... ???

我正在对完全相同的PostgreSQL的实例作为我的devserver没有...

EDIT2:原来,我的code的越野车......它未能在新SESSION_KEY在会议中未找到...

这里的固定的code ...现在try..except是在正确的位置。

 类OnlyOneUserMiddleware(对象):
    
    中间件以确保一个登录用户仅具有活跃的一个会话。
    会踢任何previous会话。
    
    高清process_request(个体经营,要求):
        如果request.user.is_authenticated():
            cur_session_key = request.user.get_profile()。session_key可以
            如果cur_session_key和cur_session_key = request.session.session_key!
                #默认处理......踢旧的会话...
                尝试:
                    S = Session.objects.get(session_key可以= cur_session_key)
                    s.delete()
                除了ObjectDoesNotExist:
                    通过
            如果不是cur_session_key或cur_session_key = request.session.session_key!
                P = request.user.get_profile()
                p.session_key = request.session.session_key
                p.save()


解决方案

您可以随时使用这个方法虽然不推荐,它的工作原理。

  my_old_sessions = Session.objects.all()
在my_old_sessions行:
   如果row​​.get_de codeD()获得(_用户名)== request.user.username:
      row.delete()

您会正确验证用户之前执行code以上的login()函数。

这当然只是如果你有一个login()函数方法存储用户在他的会议像用户名作品如下:

 的request.session [_用户名] = request.user.username

如果您使用此方法只记得运行的服务器,你所做的这些更改后,因为这将提高KeyLookUp错误之前,清空你的所有会话的数据库。

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()

解决方案

You can always use this approach though not recommended, it works.

my_old_sessions = Session.objects.all()
for row in my_old_sessions:
   if row.get_decoded().get("_username") == request.user.username:
      row.delete()

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:

request.session["_username"] = request.user.username

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应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆