如何使用 Pusher Driver 配置 Laravel 5.3 中的广播频道授权?

How to configure Channel Authorization for Broadcasting in Laravel 5.3 using Pusher Driver?

描述:

根据 Laravel 5.3 文档,当在私有或状态频道上广播事件时,在 BroadcastServiceProvider 的引导方法中必须提供一个回调来解析用户是否有权收听该频道到 Broadcast facade 方法 channel。此方法应该 return 一个布尔值。在 BroadcastServiceProvider 方法 boot 中,我们还应该包含 Broadcast::routes() ,它将定义客户端将调用以检查通道权限的身份验证路由。此路由方法可以接收一组属性以应用于路由。现在它变得奇怪了。当客户端调用此路由时,无论我将什么回调传递给 Broadcast::channel 方法,它都会给我一个 403 forbidden 除非(现在是最奇怪的部分)我为 Broadcast::routes 提供了一个带有键的数组命名为 prefix 和任意值。如果密钥不是前缀,它将返回到 403 forbidden。

HttpException in PusherBroadcaster.php line 42:

我的设置如下。我肯定做错了什么,但在我们很多人试图理解之后我无法弄清楚。有人可以给个提示吗?

重现步骤:

我创建了一个简单的事件:

<?php

namespace App\Events;

use App\Models\Presentation;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class PresentationCreated implements ShouldBroadcast
{
    use InteractsWithSockets, SerializesModels;

    public $presentation;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Presentation $presentation)
    {
        $this->presentation = $presentation;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('presentation');
    }
}

我通过调用 event(new PresentationCreated($presentation));

触发

我已经安装 "pusher/pusher-php-server": "^2.5.0" 并在 pusher 中创建了一个帐户。 我把我的 pusher 凭据放在 .env:

BROADCAST_DRIVER=pusher
PUSHER_APP_ID=*****
PUSHER_APP_KEY=*****************
PUSHER_APP_SECRET=****************
PUSHER_APP_CLUSTER=**

在我的 config\broadcast.php 我有:

'pusher' => [
        'driver' => 'pusher',
        'key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'app_id' => env('PUSHER_APP_ID'),
        'options' => [
          'cluster' => 'eu',
          'encrypted' => true,
        ],
    ],

我的客户端:

this.Echo = new Echo({
            broadcaster: 'pusher',
            key: typeof handover.pak !== 'undefined' ? handover.pak : '',
            cluster: 'eu'
        });

        this.Echo.private(`presentation`)
        .listen('PresentationCreated', (e) => {
            console.log(e, 'raposa')
        });

最后是 BroadcastServiceProvider:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;

class BroadcastServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Broadcast::routes();

        //The commented line would make the authorization pass even if I return false bellow
        //Broadcast::routes(['prefix' => 'I do not know what I am doing']);

        /*
         * Authenticate the user's personal channel...
         */
        Broadcast::channel('presentation', function ($user) {
            return false;
        });
    }
}

编辑

感谢@yazfield 的回答,我能够理解发生了什么。 http 错误是由于 $request->user() 为空。那是因为我没有传递我的路由命名空间正在使用的额外中间件。通过 Broadcast::routes(['middleware' => ['web', 'clumsy', 'admin-extra']]); 我能够解决问题。

This Laravel 问题也帮助我掌握了这件事。

通过为 routes 提供参数,您可以设置路由属性并覆盖默认为 'middleware' => ['web'] 的属性,这基本上意味着您在提供时不使用任何网络中间件任何没有 middleware 属性的数组,你都没有验证 crsfToken...等等