Laravel /broadcasting/auth 始终返回 403 错误

30

最近我开始研究Laravel 5.3的Laravel-Echo和Pusher组合。我已经成功设置了公共频道并转向了私有频道。但是在尝试授权操作时(包括使用简单的return true语句),我遇到了Laravel从/broadcasting/auth路由返回403的问题。有人能告诉我我做错了什么吗?

App/Providers/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();

        /*
         * Authenticate the user's personal channel...
         */
        Broadcast::channel('App.User.*', function ($user, $userId) {
            return true;
        });
    }
}

资源/资产/js/bootstrap.js:

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'My-Key-Here'
});

window.Echo.private('App.User.1')
    .notification((notification) => {
        console.log(notification.type);
    });

我可以在Pusher的调试控制台中看到事件和其负载,但是一旦它到达auth路由就会失败。

12个回答

0
当您尝试在我的情况下使用Laravel中的JWTTokens设置私有频道时, 为此,在/config/auth.php中,您需要建立我们将用于获取经过身份验证的用户的守卫。
    'guards' => [
    'web' => [
        'driver'   => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver'   => 'jwt',
        'provider' => 'users',
    ],
],

在上一个API守卫的代码片段中,我们从JWT获取已验证用户。
在BroadcastServiceProvider中定义路由。
class BroadcastServiceProvider extends ServiceProvider {
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Broadcast::routes();
    require base_path('routes/channels.php');
}}

在 routes/channels.php 文件中,我们为私有频道建立路由,并且在路由声明中必须添加 GUARD 选项。
Broadcast::channel('fileszipped.{id}', function ($user, $id) {
    return $user->id == $id;}, ['guards' => ['api']]);

然后,在我们用于广播消息的事件中,我们声明在已声明的通道上广播消息。您应该在此事件的构造函数中传递经过身份验证的用户:

class FileZipped implements ShouldBroadcast {

use Dispatchable, InteractsWithSockets, SerializesModels;

/**
 * The file instance.
 *
 * @var FilesUser
 */
public $fileUser;

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

/**
 * Get the channels the event should broadcast on.
 *
 * @return \Illuminate\Broadcasting\Channel|array
 */
public function broadcastOn()
{
    return new PrivateChannel('fileszipped.'.$this->fileUser->user->id);
}}

最后,在前端,我使用了 React v17 来声明它。
const options = {
    broadcaster: "pusher",
    key: "123456_key",
    cluster: "mt1",
    forceTLS: false,
    encrypted: false,
    wsHost: '127.0.0.1',
    wsPort: 6001,
    //authEndpoint is your apiUrl + /broadcasting/auth
    authEndpoint: "http://localhost:8000/broadcasting/auth",
    // As I'm using JWT tokens, I need to manually set up the headers.
    auth: {
        headers: {
            Authorization: "Bearer " + auth.accessToken,
            Accept: "application/json"
        }
    }
};

const echo = new Echo(options);

useEffect(() => {
    echo.private(`fileszipped.`+ auth.id)
        .listen('FileZipped', (e) => {
            console.log(e.fileUser.name);
            setMessage(e.fileUser.name + ' is ready for download!!');
            getAllFilesUser()
        });
}, [])

通过这样做,您将能够使用私有频道在前端接收到您的通知。尽情享受吧!

-5
-- reinstalling websockets
-- php artisan optimize:clear

4
代码转储不是好的答案。您应该解释如何为什么这样解决他们的问题。我建议阅读“如何撰写一个好答案? - John Conde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接