Django WebSocket中Token无效时无法返回自定义响应问题
Django WebSocket Consumer Token无效时返回自定义响应问题
问题场景
在Django的WebSocket Consumer中,期望Token无效时返回指定格式的自定义响应,但当前实现存在以下问题:
- 浏览器WebSocket测试客户端无法获取错误详情
- Postman返回
ECONNREFUSED错误
期望返回的错误响应格式:
{ "response": false, "return_code": "invalid_token", "result": {}, "message": "token error" }
现有代码片段(consumer.py)
some code... async def connect(self): try: self.userId = self.scope['url_route']['kwargs']['token'] try: UntypedToken(self.userId) except (InvalidToken, TokenError) as e: print(e) return {"response": False, "return_code": "invalid_token", "result": {}, "message": errors["token_not_valid"]} some code...
Postman报错信息
Error: connect ECONNREFUSED 127.0.0.1:8000 Handshake Details Request URL: http://127.0.0.1:8000/ws/users/eyJ0e.eyJ0b2In0.cbyYygG/chat/ Request Method: GET Request Headers Sec-WebSocket-Version: 13 Sec-WebSocket-Key: RpWsJRu+ziCUjwLtRjgNHg== Connection: Upgrade Upgrade: websocket Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits Host: 127.0.0.1:8000
问题原因
原代码直接返回字典的方式无效,Django Channels的connect方法不支持通过返回字典来传递响应。WebSocket握手阶段必须通过Channels提供的API处理连接状态,且只有握手完成后才能发送消息。
解决方案
采用「先接受连接→发送自定义错误响应→关闭连接」的流程,确保客户端能接收到JSON格式的错误信息:
修改后的connect方法代码:
import json from rest_framework_simplejwt.exceptions import InvalidToken, TokenError from rest_framework_simplejwt.tokens import UntypedToken async def connect(self): try: self.userId = self.scope['url_route']['kwargs']['token'] # 验证Token有效性 UntypedToken(self.userId) # Token有效时,正常接受连接并执行后续逻辑 await self.accept() # 这里添加Token有效后的业务代码 except (InvalidToken, TokenError) as e: print(e) # 先接受连接,确保能发送消息 await self.accept() # 构造并发送自定义错误响应 error_response = { "response": False, "return_code": "invalid_token", "result": {}, "message": "token error" } await self.send(text_data=json.dumps(error_response)) # 发送完成后关闭连接 await self.close()
关键说明
- 必须先调用
await self.accept()才能发送消息,否则WebSocket握手未完成,无法传递数据 - 发送错误消息后调用
await self.close(),符合Token无效时的业务逻辑 - 原代码中直接返回字典的方式不符合Channels的API规范,无法被客户端识别
内容的提问来源于stack exchange,提问作者Zain Jack
相关产品推荐
相关产品推荐

