Django请求在不同浏览器之间的会话一致性

时间:2019-06-20 07:57:33

标签: django django-sessions

我的会话引擎设置如下:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
SESSION_SAVE_EVERY_REQUEST = True
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
        'TIMEOUT': 60*60,
    }
}

我使用浏览器1 进入127.0.0.1:8000,并且可以成功登录。

然后我使用浏览器2 进入127.0.0.1:8000,并且也可以成功登录。

现在,我使用浏览器1 转到127.0.0.1:8000,并收到以下错误消息:

SuspiciousOperation at /

The request's session was deleted before the request completed.
The user may have logged out in a concurrent request, for example.

如何避免该错误?用户应该可以使用任意数量的浏览器登录。我不介意他是否从非活动浏览器中注销,但是错误是不可接受的。

1 个答案:

答案 0 :(得分:0)

问题是存在一个中间件,该中间件确保了只能同时激活一个会话。它只为会话cookie而写,并且在更广泛地重写之后,问题就消失了:

from importlib import import_module
class OnlyOneSessionMiddleware:
    """
    Middleware to ensure that a logged-in user only has one session active.
    Will kick out any previous session. 
    """
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        if request.user.is_authenticated:
            cur_session_key = request.user.profile.session_key
            if cur_session_key and cur_session_key != request.session.session_key:
                # Default handling: Kick out the old session...
                SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
                s = SessionStore(session_key=cur_session_key)
                s.delete()
                messages.add_message(request, messages.INFO, 'You have now been automatically logged out from your other Cableizer session.')
            if not cur_session_key or cur_session_key != request.session.session_key:
                request.user.profile.session_key = request.session.session_key
                request.user.profile.save()
        return response