首页 > 解决方案 > Nuxtjs + Laravel Echo + Laravel Passport + Laravel WebSockets 无法从私人/状态通道获取事件

问题描述

我正在使用与 Laravel 后端分开托管的 NuxtJS。为了对用户进行身份验证,我使用 Laravel Passport。我正在尝试使用@nuxtjs/laravel-echoand为我的网站构建聊天功能pusher-js。这是来自包的自托管 websocket beyondcode/laravel-websockets,使用php artisan websockets:serve. 作为一个例子,我正在使用这个 repo https://github.com/qirolab/Laravel-WebSockets-Chat-Example。只有我使用 Laravel-Passport 和 NuxtJS 的区别

这是我nuxt.config.js的“buildModules”部分

  buildModules: [
   ...
    [
      '@nuxtjs/laravel-echo',
      {
        broadcaster: 'pusher',
        key: process.env.MIX_PUSHER_APP_KEY,
        cluster: process.env.MIX_PUSHER_APP_CLUSTER,
        encrypted: false,
        wsHost: process.env.WEBSOCKET_BASE_URL,
        wsPort: 6001,
        disableStats: true
      }
    ]
  ],

  echo: {
    authModule: true,
    connectOnLogin: true,
    disconnectOnLogout: true
  },

我在 Laravel ( App\Events\ChatMessageSent.php) 中的事件如下所示:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\ChatMessages;

class ChatMessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;

    public function __construct(ChatMessages $message)
    {
        $this->message = $message;
    }

    public function broadcastOn()
    {
        return new PrivateChannel('chat.' . $this->message->room->id);
    }
}

目前我没有过滤用户,所以我channel.php有这个条目:

.....
Broadcast::channel('chat.{roomId}', function ($user, $roomId) {
    return true;
});

并且该事件将被调度为(我现在没有使用..->toOthers()):

...
broadcast(new ChatMessageSent($message));
...

我当前的用户在我的 NuxtJS 应用程序中进行了身份验证,并且可以通过this.$auth.user

在前端文件中我有:

mounted:{
  const channel = `chat.${this.roomID}`
  this.$echo.private(channel).listen('ChatMessageSent', event => {
      console.log(
        '-------------------- This is happening!! -----------------------'
      )
      console.log(event)
      this.messages.push(event.message)
    })

ChatMessageSent但是该应用程序在所有事件中都保持完全安静。根本没有控制台日志。如果我将其切换到公共频道,那么一切正常。我的猜测是身份验证有问题。在websocket.php配置文件中我使用 api中间件

  */
    'middleware' => [
        'api',
        Authorize::class,
    ],

有没有办法可以在 websocket 上调试身份验证过程?

顺便说一句,我在调试控制台中看不到任何有关身份验证尝试的信息http://localhost:8000/laravel-websockets

标签: laravelwebsocketnuxt.jslaravel-passportlaravel-echo

解决方案


我很幸运找到了这篇文章https://medium.com/@mihkelallorg/laravel-react-jwt-tokens-and-laravel-echo-with-pusher-for-dummies-like-me-cafc5a09a1a1

为了使上述方法起作用,第一步是(在 Laravel 方面)取消App\Providers\BroadcastServiceProvider.php注释config/app.php

'providers' => [    
    ...
    App\Providers\BroadcastServiceProvider.php,
    ...
]

然后我们需要稍微调整一下App\Providers\BroadcastServiceProvider.php以使用 API 身份验证。替换Broadcast::routes()Broadcast::routes(['middleware' => ['auth:api']]);

public function boot()
    {
        //Broadcast::routes();

        Broadcast::routes(['middleware' => ['auth:api']]);
        require base_path('routes/channels.php');
    }

现在我们只需要在(NuxtJS 端)添加一行nuxt.config.js来指定 Auth 端点。我BACKEND_BASE_URLhttp://localhost:8000网址由提供php laravel serve

buildModules: [
    ....
    [
      '@nuxtjs/laravel-echo',
      {
        broadcaster: 'pusher',
        key: process.env.MIX_PUSHER_APP_KEY,
        cluster: process.env.MIX_PUSHER_APP_CLUSTER,
        encrypted: false,
        wsHost: process.env.WEBSOCKET_BASE_URL,
        wsPort: 6001,
        disableStats: true,
        authEndpoint: process.env.BACKEND_BASE_URL + '/broadcasting/auth'
      }
    ]
  ],

  echo: {
    authModule: true,
    connectOnLogin: true,
    disconnectOnLogout: true
  },

现在私人频道正在使用自托管推送器


推荐阅读