Django Channels 从 HTTP 握手请求(升级请求)中检索 cookie

Posted

技术标签:

【中文标题】Django Channels 从 HTTP 握手请求(升级请求)中检索 cookie【英文标题】:Django Channels retrieve the cookies from the HTTP handshake request (upgrade request) 【发布时间】:2021-04-14 13:15:56 【问题描述】:

我正在尝试在 Django 频道中的连接请求开始时检索 cookie。根据正常流程,要通过 websocket 建立连接,通过 HTTP 协议执行握手,该协议应在其标头中注入浏览器具有的 cookie(与服务器域匹配)。但它没有收到它们。

为了检索服务器端 cookie,我使用了通道 cookie 中间件。

from channels.sessions import CookieMiddleware

在 Chrome 工具中,您可以看到它发送 cookie。

但在 Django 中却没有。

class CookieMiddleware:
    """
    Extracts cookies from HTTP or WebSocket-style scopes and adds them as a
    scope["cookies"] entry with the same format as Django's request.COOKIES.
    """

    def __init__(self, inner):
        self.inner = inner

    async def __call__(self, scope, receive, send):
        print("Call coockie middleware")
        print(scope) # print request
        # Check this actually has headers. They're a required scope key for HTTP and WS.
        if "headers" not in scope:
            raise ValueError(
                "CookieMiddleware was passed a scope that did not have a headers key "
                + "(make sure it is only passed HTTP or WebSocket connections)"
            )
        # Go through headers to find the cookie one
        for name, value in scope.get("headers", []):
            if name == b"cookie":
                cookies = parse_cookie(value.decode("latin1"))
                break
        else:
            # No cookie header found - add an empty default.
            cookies = 
        # Return inner application
        print(cookies) # print cookies
        return await self.inner(dict(scope, cookies=cookies), receive, send)

结果打印。

Call coockie middleware
'type': 'websocket', 'path': '/app-test/', 'raw_path': b'/app-test/', 'headers': [(b'host', b'127.0.0.1:8000'), (b'connection', b'Upgrade'), (b'pragma', b'no-cache'), (b'cache-control', b'no-cache'), (b'user-agent', b'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/86.0.4240.198 Safari/537.36'), (b'upgrade', b'websocket'), (b'origin', b'http://localhost:4200'), (b'sec-websocket-version', b'13'), (b'accept-encoding', b'gzip, deflate, br'), (b'accept-language', b'es-ES,es;q=0.9'), (b'sec-websocket-key', b'MncLnxEO1beQemafXpMt4g=='), (b'sec-websocket-extensions', b'permessage-deflate; client_max_window_bits')], 'query_string': b'', 'client': ['127.0.0.1', 55272], 'server': ['127.0.0.1', 8000], 'subprotocols': [], 'asgi': 'version': '3.0'

依赖关系

django = "==3.1.5"
channels = "==3.0.3"

感谢您的阅读以及您可以为我提供的任何帮助或指导。

【问题讨论】:

【参考方案1】:

没关系,它不会获取 cookie,因为它只会在域匹配时发送它们。因此,它无法识别 IP(数字),也无法在 IP 级别定义 cookie。这意味着当我通过 websocket 建立连接时,URL 必须为 cookie 定义域(无 IP)。

之前:

ws://127.0.0.1:8000/app-test/

之后:

ws://localhost:8000/app-test/

最后,上面的图片并不代表对 websocket 服务器的真实请求,所以即使它正在发送 cookie,它也不会将它们发送到我的服务器(这是一个不同的请求)。

【讨论】:

以上是关于Django Channels 从 HTTP 握手请求(升级请求)中检索 cookie的主要内容,如果未能解决你的问题,请参考以下文章

Django Channels - 握手和连接,但未执行 websocket.connect 函数

django-channels/websockets: WebSocketBadStatusException: 握手状态 200

向 Django-channels WebSocket 发送授权凭证(不将令牌设置为 cookie)

Django Channels 没有检测到 NGINX 的 WebSocket 请求

django 频道 channels.exceptions.Channels Full

django channels