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

Django Channels retrieve the cookies from the HTTP handshake request (upgrade request)

我正在尝试在 Django Channels 中的连接请求开始时检索 cookie。根据正常流程,要通过 websocket 建立连接,通过 HTTP 协议执行握手,该协议应在其 headers 中注入浏览器拥有的 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"

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

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

之前:

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

之后:

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

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