작성
·
43
0
안녕하세요 선생님. 인증받지 않은 유저의 웹소켓 접근을 거부하려고 하는데요,
Traceback (most recent call last):
File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/django/contrib/staticfiles/handlers.py", line 101, in __call__
return await self.application(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/routing.py", line 62, in __call__
return await application(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/sessions.py", line 47, in __call__
return await self.inner(dict(scope, cookies=cookies), receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/sessions.py", line 263, in __call__
return await self.inner(wrapper.scope, receive, wrapper.send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/auth.py", line 185, in __call__
return await super().__call__(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/middleware.py", line 24, in __call__
return await self.inner(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'list' object is not callable
WebSocket DISCONNECT /ws/chat/test/chat/ [127.0.0.1:61013]
HTTP GET /chat/ 200 [0.01, 127.0.0.1:61007]
/Users/sunnnwo/workspace/pongchat/mysite/asgi.py changed, reloading.
Watching for file changes with StatReloader
아래와 같이 설정하고 실행해봤는데, 위와 같은 에러가 발생했습니다. AuthMiddlewareStack을 이용하여 인증된 사용자만 채팅할 수 있게 하려면 어느 부분을 수정해야할까요.
감사합니다. 좋은 하루되세요.
asgi.py
application = ProtocolTypeRouter({
"http" : django_asgi_app,
"websocket" : AuthMiddlewareStack(
app.routing.websocket_urlpatterns +
chat.routing.websocket_urlpatterns,
),
})
from asgiref.sync import async_to_sync
from channels.generic.websocket import JsonWebsocketConsumer
# 모든 유저가 고정된 채널 레이어 그룹을 가질것.
class ChatConsumer(JsonWebsocketConsumer):
SQUARE_GROUP_NAME = "square"
groups = [SQUARE_GROUP_NAME]
def receive_json(self, content, **kwargs):
# user = self.scope["user"]
user = self.scope["user"]
_type = content["type"]
if not user.is_authenticated:
self.close()
else:
if _type == "chat.message":
message = content["message"]
async_to_sync(self.channel_layer.group_send)(
self.SQUARE_GROUP_NAME,
{
"type": "chat.message",
"message": message,
}
)
else:
print(f"Invalid message type : ${_type}")
def chat_message(self, message_dict):
self.send_json({
"type": "chat.message",
"message": message_dict["message"],
})
chat/routing.py
from django.urls import path, re_path
from chat import consumers
websocket_urlpatterns = [
path("ws/chat/<str:room_name>/chat/", consumers.ChatConsumer.as_asgi()),
]
chat/urls.py
urlpatterns=[
path("", views.index, name = "index"),
path("<str:room_name>/chat/", views.room_chat, name = "room_chat" ),
]
답변 1
1
안녕하세요.
TypeError: 'list' object is not callable 예외가 발생한 상황입니다. 에러 메시지를 잘 보시면 list 객체는 호출할 수 없다는 내용인데요. 리스트 객체를 호출한 상황이라는 거죠. 함수처럼 호출되어야하는 부분에 리스트 값이 들어간 상황으로 예상할 수 있습니다.
asgi.py 코드를 보시면, AuthMiddlewareStack 미들웨어 스택에 urlpatterns 리스트를 그대로 넘기고 있습니다. AuthMiddlewareStack 는 asgi app (함수처럼 호출할 수 있습니다.)을 인자로 받고, asgi app을 반환합니다. 그런데 리스트를 넘기셔서 현재의 오류가 발생하신 듯 보입니다.
urlpatterns 리스트는 URLRouter 앱으로 감싸주셔야 asgi app 으로 처리됩니다. AuthMiddlewareStack(URLRouter(urlpatterns + urlpatterns))와 같은 포맷으로 구현하심면 되실 듯 하구요.
room_chat 뷰에서 미인증 유저로부터의 요청은 거부토록 먼저 구현하구요. 웹소켓 단에서는 Consumer에서 연결요청을 받을 때 connect 메서드가 호출이 되고, 이때 연결을 수락할려면 self.accept() 를 호출하여 요청을 수락하고, 연결을 거부할려면 self.close()를 호출하시어 거부하실 수 있습니다.
살펴보시고 댓글 남겨주세요. 화이팅입니다. :-)
감사합니다. 선생님. 항상 건강하십쇼!