Django 频道 consumers.py 范围 ['user'] returns 匿名用户
Django Channels consumers.py scope['user'] returns anonymousUser
我正在尝试创建一对一聊天,但是当我尝试获取
self.scope['user']
它returnsAnonymousUser
consumers.py
class ChatConsumer(SyncConsumer):
def websocket_connect(self,event):
#error
me = self.scope['user']
other_username = self.scope['url_route']['kwargs']['username']
other_user = User.objects.get(username=other_username)
self.thread_obj = Thread.objects.get_or_create_personal_thread(me,other_user)
self.room_name = f'{self.thread_obj.id}_service'
print(f"{self.channel_name} connected")
async_to_sync(self.channel_layer.group_add)(self.room_name,self.channel_name)
self.send({
'type':'websocket.accept'
})
def websocket_receive(self,event):
print(f"{self.channel_name} message received {event['text']}")
msg = json.dumps({
'text':event.get('text'),
'username':self.scope['user'].username
})
async_to_sync(self.channel_layer.group_send)(
self.room_name,
{
'type':'websocket.message',
'text':msg
}
)
def websocket_message(self,event):
print(f"{self.channel_name} message sent {event['text']}")
self.send({
'type':'websocket.send',
'text':event.get('text')
})
def websocket_disconnect(self,event):
print(f"{self.channel_name} disconnected")
async_to_sync(self.channel_layer.group_discard)(self.room_name,self.channel_name)
print(event)
routing.py
from channels.routing import ProtocolTypeRouter,URLRouter
from django.urls import path
from .consumers import ChatConsumer,EchoConsumer
from channels.auth import AuthMiddlewareStack
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
'websocket': AuthMiddlewareStack(
URLRouter([
path('ws/chat/',EchoConsumer()),
path('ws/chat/<str:username>/',ChatConsumer()),
])
)
})
我认为问题出在auth.py:
@database_sync_to_async
def get_user(scope):
"""
Return the user model instance associated with the given scope.
If no user is retrieved, return an instance of `AnonymousUser`.
"""
# postpone model import to avoid ImproperlyConfigured error before Django
# setup is complete.
from django.contrib.auth.models import AnonymousUser
if "session" not in scope:
raise ValueError(
"Cannot find session in scope. You should wrap your consumer in "
"SessionMiddleware."
)
session = scope["session"]
user = None
try:
user_id = _get_user_session_key(session)
backend_path = session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if hasattr(user, "get_session_auth_hash"):
session_hash = session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash, user.get_session_auth_hash()
)
if not session_hash_verified:
session.flush()
user = None
return user or AnonymousUser()
因为else下的代码不是运行
我对从文档中获取的代码做了一些修改,结果是这样的
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
me = self.scope['user']
other_username = self.scope['url_route']['kwargs']['username']
other_user =await sync_to_async(User.objects.get)(username=other_username)
thread_obj =await sync_to_async(Thread.objects.get_or_create_personal_thread)(me,other_user)
self.room_name = f'{thread_obj.id}_service'
self.room_group_name = self.room_name
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
async def chat_message(self, event):
message = event['message']
await self.send(text_data=json.dumps({
'message': message
}))
我正在尝试创建一对一聊天,但是当我尝试获取
self.scope['user']
它returnsAnonymousUser
consumers.py
class ChatConsumer(SyncConsumer):
def websocket_connect(self,event):
#error
me = self.scope['user']
other_username = self.scope['url_route']['kwargs']['username']
other_user = User.objects.get(username=other_username)
self.thread_obj = Thread.objects.get_or_create_personal_thread(me,other_user)
self.room_name = f'{self.thread_obj.id}_service'
print(f"{self.channel_name} connected")
async_to_sync(self.channel_layer.group_add)(self.room_name,self.channel_name)
self.send({
'type':'websocket.accept'
})
def websocket_receive(self,event):
print(f"{self.channel_name} message received {event['text']}")
msg = json.dumps({
'text':event.get('text'),
'username':self.scope['user'].username
})
async_to_sync(self.channel_layer.group_send)(
self.room_name,
{
'type':'websocket.message',
'text':msg
}
)
def websocket_message(self,event):
print(f"{self.channel_name} message sent {event['text']}")
self.send({
'type':'websocket.send',
'text':event.get('text')
})
def websocket_disconnect(self,event):
print(f"{self.channel_name} disconnected")
async_to_sync(self.channel_layer.group_discard)(self.room_name,self.channel_name)
print(event)
routing.py
from channels.routing import ProtocolTypeRouter,URLRouter
from django.urls import path
from .consumers import ChatConsumer,EchoConsumer
from channels.auth import AuthMiddlewareStack
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
'websocket': AuthMiddlewareStack(
URLRouter([
path('ws/chat/',EchoConsumer()),
path('ws/chat/<str:username>/',ChatConsumer()),
])
)
})
我认为问题出在auth.py:
@database_sync_to_async
def get_user(scope):
"""
Return the user model instance associated with the given scope.
If no user is retrieved, return an instance of `AnonymousUser`.
"""
# postpone model import to avoid ImproperlyConfigured error before Django
# setup is complete.
from django.contrib.auth.models import AnonymousUser
if "session" not in scope:
raise ValueError(
"Cannot find session in scope. You should wrap your consumer in "
"SessionMiddleware."
)
session = scope["session"]
user = None
try:
user_id = _get_user_session_key(session)
backend_path = session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if hasattr(user, "get_session_auth_hash"):
session_hash = session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash, user.get_session_auth_hash()
)
if not session_hash_verified:
session.flush()
user = None
return user or AnonymousUser()
因为else下的代码不是运行
我对从文档中获取的代码做了一些修改,结果是这样的
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
me = self.scope['user']
other_username = self.scope['url_route']['kwargs']['username']
other_user =await sync_to_async(User.objects.get)(username=other_username)
thread_obj =await sync_to_async(Thread.objects.get_or_create_personal_thread)(me,other_user)
self.room_name = f'{thread_obj.id}_service'
self.room_group_name = self.room_name
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
async def chat_message(self, event):
message = event['message']
await self.send(text_data=json.dumps({
'message': message
}))