You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Channels聊天功能获取用户名返回空对象问题排查

问题解决:Django Channels聊天中用户名传递为空对象的问题

直接修复:前端变量名不匹配

你提到前端console里userUsername是有效用户名,但代码里发送WebSocket消息时用的是user_username——这两个变量名不一致,导致user_username处于未定义状态,JSON序列化后被后端解析为空对象。

修改前端发送逻辑里的变量名,和console里的一致:

document.querySelector('#submit').onclick = function (e) {
    const messageInputDOM = document.querySelector('#input');
    const message = messageInputDOM.value;
    chatSocket.send(JSON.stringify({
        'message': message,
        'username': userUsername, // 这里改成和console里一致的变量名
    }));
    messageInputDOM.value = '';
};

更安全的方案:从后端直接获取登录用户(推荐)

依赖前端传递用户名存在被篡改的风险,正确的做法是在Channels Consumer中直接获取已认证的登录用户信息,无需前端传递:

  1. 配置Channels认证中间件
    修改项目根目录的asgi.py,用AuthMiddlewareStack包装你的ASGI应用,确保WebSocket连接能获取用户认证信息:
import os
from django.core.asgi import get_asgi_application
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing # 替换成你的routing模块路径

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            chat.routing.websocket_urlpatterns
        )
    ),
})
  1. 修改Consumer获取用户信息
    在consumers.py中,移除前端传递的username参数,直接从self.scope中获取登录用户:
async def connect(self):
    self.room_name = self.scope['url_route']['kwargs']['room_name']
    self.room_group_name = f'chat_{self.room_name}'
    
    # 确保用户已登录
    if self.scope['user'].is_authenticated:
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()
    else:
        await self.close()

async def receive(self, text_data):
     text_data_json = json.loads(text_data)
     message = text_data_json['message']
     # 直接从scope获取用户名,无需前端传递
     username = self.scope['user'].username

     await self.channel_layer.group_send(
          self.room_group_name,
          {
               'type':'chatroom_message',
               'message':message,
               'username':username
          }
     )
  1. 前端移除username传递
    修改前端代码,不再传递username参数:
document.querySelector('#submit').onclick = function (e) {
    const messageInputDOM = document.querySelector('#input');
    const message = messageInputDOM.value;
    chatSocket.send(JSON.stringify({
        'message': message,
        // 移除username字段
    }));
    messageInputDOM.value = '';
};

这样既解决了当前的空对象问题,又避免了前端伪造用户名的安全隐患,同时头像信息也可以通过后端传递用户的头像URL一并发送。

内容的提问来源于stack exchange,提问作者user21744561

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 08:37:00