我正在尝试在具有类似架构的 Django 应用程序上添加实时更新,如下所述:http: //lincolnloop.com/blog/2012/apr/23/ginger-tech-stack/。基本上,更新通过 Redis 从 Django 发送到 Node.js,然后通过 Socket.io 推送到连接的客户端。现在,我可以向所有连接的客户端广播,但在实际情况下,我只需要向与操作相关的客户端发送数据(例如:用户发布消息,只有他的联系人/订阅者收到此消息)。所以我需要在 Node.js 端进行某种身份验证来知道谁是谁。如何实现?
问问题
2798 次
1 回答
1
到目前为止,这是我在 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 中读取会话密钥:
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']; ... });
从 sessionid 对应的 db 中检索和解码会话数据以获取用户 ID。
于 2012-05-05T13:07:04.903 回答