我正在使用Django、Django Channels和React开发一个国际象棋网络应用程序。我使用websockets在在线玩家之间玩游戏,并更新哪些玩家现在在线并可以玩游戏。然而,我在身份验证部分卡住了。我首先从令牌身份验证开始,但是我发现不可能将带有令牌的自定义头作为WebSocket请求的一部分发送,然后我又回到了默认的django.contrib.auth会话验证,不幸的是,当客户端登录并连接到WebSocket时,我无法获取他们的用户信息,就好像用户正在使用websocket的不同会话一样。当我在websocket消费者中打印self.scope[“user”]时,我获得了值AnonymousUser。请注意,我能够使用websocket交换消息,而且身份验证可以很好地与正常的HTTP请求一起工作,因为我可以防止未登录的用户访问视图。
我猜这个问题与客户端的WebSocket请求不像http请求那样访问或使用cookie进行身份验证有关。
有人遇到过类似的问题吗?他们是如何解决的?
下面是我在react中发送WebSocket消息的方式:
submitMessage = (evt) => {
//console.log("token in Messenger=",this.props.token);
evt.preventDefault();
const message = { message: this.state.message_to_send}
this.ws.send(JSON.stringify(message))
}
这是处理WebSocket请求的后端代码:
from channels.generic.websocket import WebsocketConsumer
import json
from asgiref.sync import async_to_sync
class LoggedUsersConsumer(WebsocketConsumer):
def connect(self):
self.user = self.scope["user"]
print(self.scope)
print(self.user,"+++++++++++++")
#Join group
async_to_sync(self.channel_layer.group_add)(
"logged_users",
self.channel_name
)
self.accept()
def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)(
"logged_users",
self.channel_name
)
def receive(self, text_data):
self.user = self.scope["user"]
print(self.user,"+++++++++++++")
text_data_json = json.loads(text_data)
print(text_data_json)
message = text_data_json['message']
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
"logged_users",
{
'type': 'logged_user_message',
'message': message
}
)
def logged_user_message(self, event):
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps({
'message': message
}))
2条答案
按热度按时间r8uurelv1#
我认为你是对的,你可能没有一个会话cookie来处理来自客户端的请求,这就是为什么你得到了AnonymousUser。我不认为这与你在React和Django中处理WebSocket请求的方式有任何关系。
请检查你的React前端浏览器的cookies(通过Chrome/Firefox的开发者工具)。你应该至少有两个cookies,csrftoken和sessionid。如果缺少其中任何一个,下面的方法可能会帮助你找到正确的方向。我在使用Vue,Django Channels和Django Rest Framework开发时也有过同样的经历。
如果您通过浏览器访问Django后端,HTML模板和浏览器会负责设置cookie。当您从React或Vue进行此操作时,HTML不会呈现。因此,您需要自己实现身份验证和cookie设置。当然,您需要在稍后用于访问Web套接字的同一会话中从React进行身份验证。
我使用以下Django视图从前端进行身份验证:
在您的www.example.com中urls.py,您需要添加如下内容:
现在你可以从你的前端做一些类似的事情(以下是我的javascript/Vue代码,为这篇文章稍微做了一些调整,但是你可能可以用React做一些类似的事情):
我希望这对你有帮助。如果没有,请告诉我。
41zrol4v2#
我再补充一句也许能帮上忙,
您总是得到AnonymousUser,因为您可能没有正确传递cookie标头。
使用会话身份验证,像这样传递会话头。
你可以试着
那没用的