Django 频道中的 self.scope['user'] 始终显示为 AnonymousUser

haf*_*acc 5 django scope websocket reactjs django-channels

当我登录到我的前端时,我的 self.scope['user'] 在 django 通道中调用 myfriends.consumer.py 返回 AnonymousUser,但是当登录并在我的 chat.consumer 中调用 self.scope['user'] 时,会返回 AnonymousUser。 py 它显示为登录用户。由于某种原因,我的一个应用程序中的范围['user']可以工作,而另一个应用程序则不能。我不明白问题是什么。我在 django 项目中设置了路由,如下所示

路由.py

from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import chat.routing
import friends.routing

application = ProtocolTypeRouter ({
    'websocket': AuthMiddlewareStack(
        URLRouter(
        friends.routing.websocket_urlpatterns + chat.routing.websocket_urlpatterns
        )
    )
})
Run Code Online (Sandbox Code Playgroud)

我的第二个 Consumer.py 结构与第一个 Consumer.py 类似。这是我的consumer.py,scope['user']在其中工作(我不需要第一个消费者中的scope['user'],但我只是想测试一下它是否有效

聊天消费者.py

class ChatConsumer(WebsocketConsumer):
  ...
   def connect(self):
    print(self.scope['user'])
    self.room_name = self.scope['url_route']['kwargs']['room_name']
    self.room_group_name = 'chat_%s' % self.room_name

    # Join room group
    async_to_sync (self.channel_layer.group_add)(
        self.room_group_name,
        self.channel_name
    )

    self.accept()
Run Code Online (Sandbox Code Playgroud)

此代码是消费者,即使我登录后,我的范围['user']也显示为匿名用户。

朋友.consumer.py

class FriendRequestConsumer(JsonWebsocketConsumer):
    def connect(self):
        user = self.scope['user']
        grp = 'notifications_{}'.format(user.username)
        self.accept()
        async_to_sync(self.channel_layer.group_add(grp, self.channel_name))
Run Code Online (Sandbox Code Playgroud)

这也是我每个应用程序的routing.py

朋友.路由.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r'^ws/friend-request-notification/$', consumers.FriendRequestConsumer),
]
Run Code Online (Sandbox Code Playgroud)

聊天路由.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer),
]
Run Code Online (Sandbox Code Playgroud)

我能够在我的reactjs前端连接到它们的websocket。我知道 AuthMiddlewareStack 允许我们拉取范围['user'],我只是不明白为什么一个有效,一个有效。难道是我没有在前端正确连接到 websocket 或者我在我的一个消费者身上遗漏了一些东西?我提前感谢您的帮助和感谢。

为了连接到我的 js 中的 websocket,我制作了一个 chat.js 文件和一个 notification.js

聊天.js

class Chat extends React.Component{
  ... 
   initialiseChat() {
this.waitForSocketConnection(()=> {
  WebSocketInstance.fetchMessages(
    this.props.username,
    this.props.match.params.id
   )
  })
WebSocketInstance.connect(this.props.match.params.id)
}
constructor(props){
  super(props)
  this.initialiseChat()
}
Run Code Online (Sandbox Code Playgroud)

通知.js

class Notifications extends React.Component{
   ...
  initialiseNotification(){
  this.waitForSocketConnection(() => {
    NotificationWebSocketInstance.fetchFriendRequests(
     this.props.id
  )
  })
  NotificationWebSocketInstance.connect()
}

constructor(props){
  super(props)
  this.initialiseNotification()
}
Run Code Online (Sandbox Code Playgroud)

这是我的 websocket 操作:

webosocket.js(此连接函数在 chat.js 中调用)

class WebSocketService {
  ...
  connect(chatUrl) {
const path ='ws://127.0.0.1:8000/ws/chat/'+chatUrl+'/';
console.log(path)
this.socketRef = new WebSocket(path)
this.socketRef.onopen = () => {
  console.log('websocket open')

}
...
const WebSocketInstance = WebSocketService.getInstance();
export default WebSocketInstance;
Run Code Online (Sandbox Code Playgroud)

这是 notification.js 的 websocket

notificationWebsocket.js

class WebSocketNotifications {
 ...
 connect(){
 const path = 'ws://127.0.0.1:8000/ws/friend-request-notification/'
 console.log(path)
 this.socketRef = new WebSocket(path)
 this.socketRef.onopen = () =>{
   console.log('websocket open')
 }
 ...
 const NotificationWebSocketInstance = 
  WebSocketNotifications.getInstance();

 export default NotificationWebSocketInstance;
Run Code Online (Sandbox Code Playgroud)

这是routes.js

class BaseRouter extends React.Component {
  <Route exact path = '/chat/:id' render={(props) => <Chat {...props} 
      {...this.props} isAuthenticated={this.props.isAuthenticated} />}  
      />
    <Route exact path = '/notifications/' render={(props) => 
       <Notifications {...props} {...this.props} isAuthenticated= 
       {this.props.isAuthenticated} />}  />
Run Code Online (Sandbox Code Playgroud)

小智 0

您的令牌中间件肯定存在一些问题