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 请求