gpt4 book ai didi

Django 3.0 + Channels + ASGI + TokenAuthMiddleware

转载 作者:行者123 更新时间:2023-12-03 15:13:27 25 4
gpt4 key购买 nike

我升级到 Django 3.0,现在使用 websockets + TokenAuthMiddleware 时出现此错误:

SynchronousOnlyOperation
You cannot call this from an async context - use a thread or sync_to_async.

最佳答案

问题是您无法从异步上下文访问同步代码。这是一个 TokenAuthMiddleware对于 Django 3.0:

# myproject.myapi.utils.py
from channels.auth import AuthMiddlewareStack
from channels.db import database_sync_to_async
from django.contrib.auth.models import AnonymousUser

from rest_framework.authtoken.models import Token


@database_sync_to_async
def get_user(headers):
try:
token_name, token_key = headers[b'authorization'].decode().split()
if token_name == 'Token':
token = Token.objects.get(key=token_key)
return token.user
except Token.DoesNotExist:
return AnonymousUser()


class TokenAuthMiddleware:

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

def __call__(self, scope):
return TokenAuthMiddlewareInstance(scope, self)


class TokenAuthMiddlewareInstance:
"""
Yeah, this is black magic:
https://github.com/django/channels/issues/1399
"""
def __init__(self, scope, middleware):
self.middleware = middleware
self.scope = dict(scope)
self.inner = self.middleware.inner

async def __call__(self, receive, send):
headers = dict(self.scope['headers'])
if b'authorization' in headers:
self.scope['user'] = await get_user(headers)
inner = self.inner(self.scope)
return await inner(receive, send)


TokenAuthMiddlewareStack = lambda inner: TokenAuthMiddleware(AuthMiddlewareStack(inner))

像这样使用它:
# myproject/routing.py
from myapi.utils import TokenAuthMiddlewareStack
from myapi.websockets import WSAPIConsumer

application = ProtocolTypeRouter({
"websocket": TokenAuthMiddlewareStack(
URLRouter([
path("api/v1/ws", WSAPIConsumer),
]),
),

})
application = SentryAsgiMiddleware(application)

关于Django 3.0 + Channels + ASGI + TokenAuthMiddleware,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60009296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com