如何从 Django Channels 网络套接字数据包中获取当前用户?
How to get current user from a Django Channels web socket packet?
我正在学习本教程:Finally, Real-Time Django Is Here: Get Started with Django Channels。
我想通过使用 Django User 对象而不是 handle
变量来扩展应用程序。 但是如何在我的 ws_recieve(message)
函数中从接收到的 WebSocket 数据包中获取当前用户?
我注意到网络套接字数据包中的 csrftoken
和 sessionid
的前十位数字都匹配正常的 HTTP 请求。我可以使用此信息获取当前用户吗?
作为参考,收到的数据包如下所示:
{'channel': <channels.channel.Channel object at 0x110ea3a20>,
'channel_layer': <channels.asgi.ChannelLayerWrapper object at 0x110c399e8>,
'channel_session': <django.contrib.sessions.backends.db.SessionStore object at 0x110d52cc0>,
'content': {'client': ['127.0.0.1', 52472],
'headers': [[b'connection', b'Upgrade'],
[b'origin', b'http://0.0.0.0:8000'],
[b'cookie',
b'csrftoken=EQLI0lx4SGCpyTWTJrT9UTe1mZV5cbNPpevmVu'
b'STjySlk9ZJvxzHj9XFsJPgWCWq; sessionid=kgi57butc3'
b'zckszpuqphn0egqh22wqaj'],
[b'cache-control', b'no-cache'],
[b'sec-websocket-version', b'13'],
[b'sec-websocket-extensions',
b'x-webkit-deflate-frame'],
[b'host', b'0.0.0.0:8000'],
[b'upgrade', b'websocket'],
[b'sec-websocket-key', b'y2Lmb+Ej+lMYN+BVrSXpXQ=='],
[b'user-agent',
b'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) '
b'AppleWebKit/602.1.50 (KHTML, like Gecko) Version'
b'/10.0 Safari/602.1.50'],
[b'pragma', b'no-cache']],
'order': 0,
'path': '/chat-message/',
'query_string': '',
'reply_channel': 'websocket.send!UZaOWhupBefN',
'server': ['127.0.0.1', 8000]},
'reply_channel': <channels.channel.Channel object at 0x110ea3a90>}
注意:这个问题是针对Channels 1.x
和Django
会话系统的,如果你是来Channels 2.x
的,请阅读下面 link 的文档,他们非常清楚如何做到这一点,Channels 1.x
文档让一些人(包括我)感到困惑,这就是为什么这个问题和其他问题Channels 2.x
文档 crystal 清楚地说明了如何实现这一点:
https://channels.readthedocs.io/en/latest/topics/authentication.html#django-authentication
频道 1.x:
您可以通过更改 consumers.py
中的装饰器以匹配文档来访问 message
的 user
和 http_session
属性:
You get access to a user’s normal Django session using the http_session decorator
- that gives you a message.http_session
attribute that behaves just like request.session
. You can go one further and use http_session_user
which will provide a message.user
attribute as well as the session attribute.
所以示例中的consumers.py
文件应该变成如下:
from channels.auth import http_session_user, channel_session_user, channel_session_user_from_http
@channel_session_user_from_http
def ws_connect(message):
...
...
@channel_session_user
def ws_receive(message):
# You can check for the user attr like this
log.debug('%s', message.user)
...
...
@channel_session_user
def ws_disconnect(message):
...
...
注意装饰器的变化。
另外,我建议你不要在那个例子的基础上构建任何东西
有关详细信息,请参阅:https://channels.readthedocs.io/en/1.x/getting-started.html#authentication
2018 年更新答案via the docs:
To access the user, just use self.scope["user"] in your consumer code:
class ChatConsumer(WebsocketConsumer):
def connect(self, event):
self.user = self.scope["user"]
def receive(self, event):
username_str = None
username = self.scope["user"]
if(username.is_authenticated()):
username_str = username.username
print(type(username_str))
#pdb.set_trace() # optional debugging
我正在学习本教程:Finally, Real-Time Django Is Here: Get Started with Django Channels。
我想通过使用 Django User 对象而不是 handle
变量来扩展应用程序。 但是如何在我的 ws_recieve(message)
函数中从接收到的 WebSocket 数据包中获取当前用户?
我注意到网络套接字数据包中的 csrftoken
和 sessionid
的前十位数字都匹配正常的 HTTP 请求。我可以使用此信息获取当前用户吗?
作为参考,收到的数据包如下所示:
{'channel': <channels.channel.Channel object at 0x110ea3a20>,
'channel_layer': <channels.asgi.ChannelLayerWrapper object at 0x110c399e8>,
'channel_session': <django.contrib.sessions.backends.db.SessionStore object at 0x110d52cc0>,
'content': {'client': ['127.0.0.1', 52472],
'headers': [[b'connection', b'Upgrade'],
[b'origin', b'http://0.0.0.0:8000'],
[b'cookie',
b'csrftoken=EQLI0lx4SGCpyTWTJrT9UTe1mZV5cbNPpevmVu'
b'STjySlk9ZJvxzHj9XFsJPgWCWq; sessionid=kgi57butc3'
b'zckszpuqphn0egqh22wqaj'],
[b'cache-control', b'no-cache'],
[b'sec-websocket-version', b'13'],
[b'sec-websocket-extensions',
b'x-webkit-deflate-frame'],
[b'host', b'0.0.0.0:8000'],
[b'upgrade', b'websocket'],
[b'sec-websocket-key', b'y2Lmb+Ej+lMYN+BVrSXpXQ=='],
[b'user-agent',
b'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) '
b'AppleWebKit/602.1.50 (KHTML, like Gecko) Version'
b'/10.0 Safari/602.1.50'],
[b'pragma', b'no-cache']],
'order': 0,
'path': '/chat-message/',
'query_string': '',
'reply_channel': 'websocket.send!UZaOWhupBefN',
'server': ['127.0.0.1', 8000]},
'reply_channel': <channels.channel.Channel object at 0x110ea3a90>}
注意:这个问题是针对Channels 1.x
和Django
会话系统的,如果你是来Channels 2.x
的,请阅读下面 link 的文档,他们非常清楚如何做到这一点,Channels 1.x
文档让一些人(包括我)感到困惑,这就是为什么这个问题和其他问题Channels 2.x
文档 crystal 清楚地说明了如何实现这一点:
https://channels.readthedocs.io/en/latest/topics/authentication.html#django-authentication
频道 1.x:
您可以通过更改 consumers.py
中的装饰器以匹配文档来访问 message
的 user
和 http_session
属性:
You get access to a user’s normal Django session using the
http_session decorator
- that gives you amessage.http_session
attribute that behaves just likerequest.session
. You can go one further and usehttp_session_user
which will provide amessage.user
attribute as well as the session attribute.
所以示例中的consumers.py
文件应该变成如下:
from channels.auth import http_session_user, channel_session_user, channel_session_user_from_http
@channel_session_user_from_http
def ws_connect(message):
...
...
@channel_session_user
def ws_receive(message):
# You can check for the user attr like this
log.debug('%s', message.user)
...
...
@channel_session_user
def ws_disconnect(message):
...
...
注意装饰器的变化。
另外,我建议你不要在那个例子的基础上构建任何东西
有关详细信息,请参阅:https://channels.readthedocs.io/en/1.x/getting-started.html#authentication
2018 年更新答案via the docs:
To access the user, just use self.scope["user"] in your consumer code:
class ChatConsumer(WebsocketConsumer):
def connect(self, event):
self.user = self.scope["user"]
def receive(self, event):
username_str = None
username = self.scope["user"]
if(username.is_authenticated()):
username_str = username.username
print(type(username_str))
#pdb.set_trace() # optional debugging