【问题标题】:Django Channels ERROR: TypeError: object.__init__() takes exactly one argument (the instance to initialize)Django Channels ERROR: TypeError: object.__init__() 只采用一个参数(要初始化的实例)
【发布时间】:2021-07-11 17:25:58
【问题描述】:

我正在使用自定义 JWT 身份验证中间件来验证 JWT。

import jwt
from urllib.parse import parse_qs
from channels.db import database_sync_to_async
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from django.conf import settings
from rest_framework_simplejwt.tokens import AccessToken


@database_sync_to_async
def get_user(user_id):
    User = get_user_model()
    try:
        user = User.objects.get(id=user_id)
        return user
    except User.DoesNotExist:
        return AnonymousUser()


class TokenAuthMiddleware:
    """
    Custom middleware (insecure) that takes user IDs from the query string.
    """

    def __init__(self, inner):
        # Store the ASGI application we were passed
        self.inner = inner

    async def __call__(self, scope, receive, send):
        # Look up user from query string (you should also do things like
        # checking if it is a valid user ID, or if scope["user"] is already
        # populated).
        token = parse_qs(scope["query_string"].decode())["token"][0]
        AccessToken(token).verify()
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'])
        scope["user"] = await get_user(int(payload["user_id"]))
        return await self.inner(dict(scope), receive, send)

我收到错误TypeError: object.__init__() takes exactly one argument (the instance to initialize)

我关注了官方docs

谁能指导我到底是哪里出了问题?

【问题讨论】:

  • 作用域周围的 dict() 是什么?
  • @Melvyn 是的,这没有任何意义。我不久后将其删除,但这并没有解决问题

标签: django django-rest-framework django-channels


【解决方案1】:

对于任何面临同样问题的人来说,问题实际上并不在于中间件。就我而言,问题出在asgi.py。我忘了在consumer 上调用.as_asgi() 方法。

application = ProtocolTypeRouter(
    {
        "http": get_asgi_application(),
        # Just HTTP for now. (We can add other protocols later.)
        "websocket": TokenAuthMiddlewareStack(
            URLRouter([
                path("chat/", ChatConsumer.as_asgi()),
            ])
        )
    }
)

注意ChatConsumer 上的as_asgi() 方法。我错过了最终导致我认为问题出在我的自定义中间件的问题。

【讨论】:

  • 是的,这是新的 3.0+ 协议。感谢您分享根本原因,我相信您不会是最后一个遇到此问题的人。
猜你喜欢
  • 2019-12-31
  • 2020-01-25
  • 1970-01-01
  • 2020-11-14
  • 2021-09-15
  • 2021-12-19
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多