如何从Django Channels Web套接字数据包中获取当前用户?

use*_*434 5 python sockets django session django-channels

我正在学习本教程:最后,Real-Time Django就在这里:开始使用Django频道.

我想通过使用Django User对象而不是handle变量来扩展应用程序.但是如何在我的ws_recieve(message)函数中从收到的WebSocket数据包中获取当前用户?

我注意到Web套接字数据包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>}
Run Code Online (Sandbox Code Playgroud)

Has*_*nPy 5

注意:这个问题是特定于Channels 1.xDjango会议系统,如果你是这里Channels 2.x的方式,请从下面的链接阅读文档,它们比更清楚如何做到这一点,Channels 1.x文档被迷惑了一些人(包括me),这就是为什么这个问题和其他问题的原因,Channels 2.x文档清楚地说明了如何实现这个目标:https:
//channels.readthedocs.io/en/latest/topics/authentication.html#django-authentication


渠道1.x:

您可以通过更改装饰器来访问您的a userhttp_session属性以匹配文档:messageconsumers.py

您可以使用 - 来访问用户的正常Django会话http_session decorator- 这会为您提供一个message.http_session行为就像的属性request.session.您可以进一步使用http_session_user,它将提供message.user属性以及会话属性.

所以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):  
    ...  
    ...  
Run Code Online (Sandbox Code Playgroud)

注意装饰器改变了.
另外,我建议你不要在那个例子上构建任何东西

有关详细信息,请参阅:https://channels.readthedocs.io/en/1.x/getting-started.html#authentication


Sco*_*les 5

通过docs在2018年更新了答案:

要访问用户,只需在使用者代码中使用self.scope [“ user”]:

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
Run Code Online (Sandbox Code Playgroud)