【问题标题】:How to get current user from a Django Channels web socket packet?如何从 Django Channels Web 套接字数据包中获取当前用户?
【发布时间】:2017-02-21 16:11:23
【问题描述】:

我正在关注本教程:Finally, Real-Time Django Is Here: Get Started with Django Channels

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

我注意到来自网络套接字数据包的csrftokensessionid 的前十位数字都与正常的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>}

【问题讨论】:

    标签: python django sockets session django-channels


    【解决方案1】:

    注意:这个问题是针对Channels 1.xDjango 会话系统的,如果您在这里使用Channels 2.x 方式,请阅读下面链接中的文档,他们'关于如何做到这一点非常清楚,Channels 1.x 文档让某些人(包括我)感到困惑,这就是为什么提出这个问题和其他问题的原因,Channels 2.x 文档非常清楚如何实现这一点:https://channels.readthedocs.io/en/latest/topics/authentication.html#django-authentication


    频道 1.x:

    您可以通过更改consumers.py 中的装饰器以匹配文档来访问messageuserhttp_session 属性:

    您可以使用 http_session decorator 访问用户的正常 Django 会话 - 它为您提供了一个行为类似于 request.sessionmessage.http_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):  
        ...  
        ...  
    

    注意装饰器的变化
    另外,我建议您不要在该示例上构建任何内容

    更多详情请见:https://channels.readthedocs.io/en/1.x/getting-started.html#authentication

    【讨论】:

    • 感谢您的帮助!如果我理解正确channel_session_user 添加了message.user 属性,但我仍然需要使用channel_session 来保存其他数据对吗?
    • 是的,文档是这样说的:Channels provides a channel_session decorator for this purpose - it provides you with an attribute called message.channel_session that acts just like a normal Django session.
    【解决方案2】:

    2018年更新答案via the docs

    要访问用户,只需在您的消费者代码中使用 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-22
      • 2022-06-10
      • 2020-02-21
      • 2017-10-28
      • 2021-06-16
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多