简体   繁体   English

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

[英]How to get current user from a Django Channels web socket packet?

I was following this tutorial: Finally, Real-Time Django Is Here: Get Started with Django Channels . 我正在学习本教程: 最后,实时Django在这里:Django Channels入门

I wanted to extend the app by using Django User objects instead of the handle variable. 我想通过使用Django User对象而不是handle变量来扩展应用程序。 But how can I get the current user from the received WebSocket packet in my ws_recieve(message) function? 但是,如何从ws_recieve(message)函数中收到的WebSocket数据包中获取当前用户?

I noticed that both the csrftoken and the first ten digits of sessionid from the web socket packet match a normal HTTP request. 我注意到, csrftoken和来自Web套接字数据包的sessionid的前十个数字都与正常的HTTP请求匹配。 Can I get the current user with this information? 我可以获取当前用户的信息吗?

For reference the received packet looks like this: 作为参考,接收到的数据包如下所示:

{'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>}

Note : The question is specific to Channels 1.x and the Django session system, if you're here for Channels 2.x way, please read the docs from the link below, they're more than clear on how to do this, the Channels 1.x docs were confusing for some people (including me), this is why this question and others were made, the Channels 2.x docs are crystal clear on how to achieve this: 注意 :该问题特定于Channels 1.xDjango会话系统,如果您使用Channels 2.x方法,请阅读下面链接中的文档,他们对于如何执行此操作非常清楚, Channels 1.x文档使某些人(包括我)感到困惑,这就是为什么这个问题和其他问题引起的原因, Channels 2.x文档非常清楚如何实现此目的:
https://channels.readthedocs.io/en/latest/topics/authentication.html#django-authentication https://channels.readthedocs.io/zh-CN/latest/topics/authentication.html#django-authentication


Channels 1.x: 频道1.x:

You can get access to a user and http_session attributes of your message by changing the decorators in consumers.py to match the docs: 您可以通过更改consumers.py的修饰符以匹配文档来访问messageuserhttp_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 . 您可以使用http_session decorator访问用户的常规Django会话-这会向您提供message.http_session属性,其行为类似于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. 您可以进一步使用http_session_user ,它将提供message.user属性以及session属性。

so the consumers.py file in the example should become the following: 因此示例中的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):  
    ...  
    ...  

Notice the decorators change . 请注意装饰器更改
Also, i suggest you don't build anything upon that example 另外,我建议您不要在该示例上构建任何东西

for more details see: https://channels.readthedocs.io/en/1.x/getting-started.html#authentication 有关更多详细信息,请参见: https : //channels.readthedocs.io/en/1.x/getting-started.html#authentication

Updated answer in 2018 via the docs : 通过docs在2018年更新了答案:

To access the user, just use self.scope["user"] in your consumer code: 要访问用户,只需在使用者代码中使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM