使用Django/Redis/Node.js实时推/拉

使用Django/Redis/Node.js实时推/拉,django,node.js,redis,Django,Node.js,Redis,我正在尝试在Django应用程序上添加实时更新,该应用程序具有类似的体系结构,如下所述:。基本上,更新通过Redis从Django发送到Node.js,然后通过Socket.io推送到连接的客户端。现在,我可以向连接的每个客户端广播,但在实际情况中,我只需要向与某个操作相关的客户端发送数据(例如:用户发布消息,只有他的联系人/订阅者接收此消息)。所以我需要在Node.js端进行某种身份验证才能知道谁是谁。如何实现这一点?这是我目前在socket.io/node.js中获取连接用户身份的解决方案(

我正在尝试在Django应用程序上添加实时更新,该应用程序具有类似的体系结构,如下所述:。基本上,更新通过Redis从Django发送到Node.js,然后通过Socket.io推送到连接的客户端。现在,我可以向连接的每个客户端广播,但在实际情况中,我只需要向与某个操作相关的客户端发送数据(例如:用户发布消息,只有他的联系人/订阅者接收此消息)。所以我需要在Node.js端进行某种身份验证才能知道谁是谁。如何实现这一点?

这是我目前在socket.io/node.js中获取连接用户身份的解决方案(如果您有更好的解决方案,请随时发布):

在Django一侧:

  • 修补Django以使用json而不是pickle对象来存储会话数据:

        diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py
    index 5a637e2..cb4db54 100644
    --- a/django/contrib/sessions/backends/base.py
    +++ b/django/contrib/sessions/backends/base.py
    @@ -2,9 +2,9 @@
     import time
     from datetime import datetime, timedelta
     try:
    -    import cPickle as pickle
    +    import json
     except ImportError:
    -    import pickle
    +    import simplejson as json
    
     from django.conf import settings
     from django.core.exceptions import SuspiciousOperation
    @@ -75,21 +75,21 @@ def _hash(self, value):
             return salted_hmac(key_salt, value).hexdigest()
    
         def encode(self, session_dict):
    -        "Returns the given session dictionary pickled and encoded as a string."
    -        pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
    -        hash = self._hash(pickled)
    -        return base64.encodestring(hash + ":" + pickled)
    +        "Returns the given session dictionary as json and encoded as a string."
    +        data = json.dumps(session_dict)
    +        hash = self._hash(data)
    +        return base64.encodestring(hash + ":" + data)
    
         def decode(self, session_data):
             encoded_data = base64.decodestring(session_data)
             try:
                 # could produce ValueError if there is no ':'
    -            hash, pickled = encoded_data.split(':', 1)
    -            expected_hash = self._hash(pickled)
    +            hash, data = encoded_data.split(':', 1)
    +            expected_hash = self._hash(data)
                 if not constant_time_compare(hash, expected_hash):
                     raise SuspiciousOperation("Session data corrupted")
                 else:
    -                return pickle.loads(pickled)
    +                return json.loads(data)
             except Exception:
                 # ValueError, SuspiciousOperation, unpickling exceptions. If any of
                 # these happen, just return an empty dictionary (an empty session).
    
在Node.js端:

  • 从“sessionid”cookie读取会话密钥:

  • 从会话id对应的数据库中检索并解码会话数据,以获取用户id


假设Django和Node位于同一主机名上,并且Django中有基于cookie的身份验证,因此Node可以读取这些cookie,您可以为Node编写Django身份验证适配器。好的,所以我从数据库备份移动到基于cookie的会话,并且可以读取节点端的«sessionid»cookie。所以现在我想我必须移植到节点…对不起--我不清楚基于cookie的身份验证是什么意思:如果你可以从节点访问同一个数据库,你应该能够使用db支持的会话,我只是说使用cookie作为会话ID。这两种解决方案都应该很好。是的,我会是你的朋友。嗯,在搜索解决方案时,我认为从Node.js访问数据库会过于复杂,但这可能比使用Django签名的cookies容易得多。我想用这种方法试试。谢谢你指出;)因此,现在我可以根据cookie的会话id从db中检索会话数据。我以为会话数据是base64,但它似乎是特定于python的(pickle,我不太熟悉)…有没有一种方法可以在节点端对其进行解码?当您可以编写自己的会话后端时,为什么要修补Django?是的,可能确实更好。所以我尝试扩展Django db会话后端:但它不能正常工作。不知道怎么了。。。我可以登录,cookie&db条目似乎已正确创建,但当我访问登录所需的受保护视图时,我会被重定向到登录页面。。。
socket.on('connection', function(client) {
    ...
    var cookie_string = client.handshake.headers.cookie;
    var parsed_cookies = connect.utils.parseCookie(cookie_string);
    var sessionid = parsed_cookies['sessionid'];
    ...
});