Laravel echo - 无法通过私有频道进行身份验证

Posted

技术标签:

【中文标题】Laravel echo - 无法通过私有频道进行身份验证【英文标题】:Laravel echo - could not be authenticated to private Channel 【发布时间】:2019-01-04 03:23:07 【问题描述】:

我正在尝试使用私有通道对 laravel 回显进行身份验证。每次我得到 "could not be authenticated to private-basket_details.1 " 。 "basket_details" 这是频道名称,1 是参数。

当我使用公共频道时,一切正常。所以我认为身份验证部分存在一些问题。

这是我的错误日志

⚠ [14:42:55] - 5eKrT28nX7uLHEkLAAAG could not be authenticated to private-basket_details.1

    "message": "",
    "exception": "Symfony\Component\HttpKernel\Exception\NotFoundHttpException",
    "file": "/var/www/html/Laravel/uneek_clothing/trunk/public_html/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php",
    "line": 179,
    "trace": [
        
            "file": "/var/www/html/Laravel/uneek_clothing/trunk/public_html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 612,
            "function": "match",
            "class": "Illuminate\Routing\RouteCollection",
            "type": "->"
        ,
        
            "file": "/var/www/html/Laravel/uneek_clothing/trunk/public_html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 601,
            "function": "findRoute",
            "class": "Illuminate\Routing\Router",
            "type": "->"
        ,
        

这是我的活动文件。

<?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 Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use App\Basket;
use App\User;

class UpdateWebOrderDetailsToBasket implements ShouldBroadcastNow

    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $basket;

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

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


这是我的频道.php

<?php
// use Illuminate\Broadcasting\PrivateChannel;

/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/

Broadcast::channel('App.User.id', function ($user, $id) 
    return (int) $user->id === (int) $id;
);

// Broadcast::PrivateChannel('basket.basketId', function ($user, $basketId) 
//     return true;
// );

// Broadcast::channel('basket_details.1', function ($user, $basketId) 
//     return true;
// );

Broadcast::channel('basket_details.basketId', function ($user, $basketId) 
    return true;
);

// Broadcast::channel('private-basket_details.*', function ($user, $basketId) 
//     return true;
// );

这是我的 js 文件

Echo.private('basket_details.1')
    .listen('.App\Events\UpdateWebOrderDetailsToBasket', (e) => 
      console.log("channel started here");
    ); 

这是我的 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();

        require base_path('routes/channels.php');
    

这是我的 laravel-echo-server.json


    "authHost": "http://192.168.1.120:1002",
    "authEndpoint": "/broadcasting/auth",
    "clients": [
        
            "appId": "be17370a567448f7",
            "key": "7af893ebfa188744e6317b30a481824f"
        
    ],
    "database": "redis",
    "databaseConfig": 
        "redis": ,
        "sqlite": 
            "databasePath": "/database/laravel-echo-server.sqlite"
        
    ,
    "devMode": true,
    "host": null,
    "port": "9999",
    "protocol": "http",
    "socketio": ,
    "sslCertPath": "",
    "sslKeyPath": "",
    "sslCertChainPath": "",
    "sslPassphrase": "",
    "apiOriginAllow": 
        "allowCors": true,
        "allowOrigin": "http://192.168.1.120:9999",
        "allowMethods": "GET,POST",
        "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
    

【问题讨论】:

同样的问题,以前没有。你找到解决办法了吗? 不,使用公共频道@Shadrix 到今天,还没有解决办法? @AravindSrinivas 我也偶然发现了这个问题。我是这个主题的菜鸟,在这种情况下使用 Channel 而不是 PrivateChannel 会有什么缺点? 我不得不将我的socket.io-client 从版本3.* 移动到2.2.0。对我来说,这一直是个问题。与Laravellaravel-echo-server 无关 【参考方案1】:

你是不是忘记在 config/app.php 中取消注释 BroadcastServiceProvider::class

App\Providers\BroadcastServiceProvider::class

【讨论】:

【参考方案2】:

可能存在问题的一件事是您正在侦听的事件命名空间。文档显示使用点符号而不是反斜杠:

Echo.private('basket_details.1')
  // change this to '.App.Events.UpdateWebOrderDetailsToBasket' 
  // or just 'UpdateWebOrderDetailsToBasket' since you are using the default App\Events.
  .listen('.App\Events\UpdateWebOrderDetailsToBasket', (e) => 
    console.log("channel started here");
  );

见Namespaces

您能否验证正在到达正确的授权路径?如果您从以下位置登录,是否会打印任何内容:

Broadcast::channel('basket_details.basketId', function ($user, $basketId) 
    logger('Basked ID: ' . $basketId);
    return true;
);

例如,如果您使用 api 中间件保护这些路由,则需要使用正确的标头创建 Echo 实例:

const client = new Echo(
  auth: 
    headers: 
      Authorization: `Bearer $token`
    
  
)

【讨论】:

记录器没有记录,我没有使用任何 api 的 NotFoundHttpException 可能会揭示问题,尝试记录来自app/Exceptions/Handler.php 的异常,以查看是否会打印更多信息性消息或堆栈跟踪。【参考方案3】:

&lt;meta name="csrf-token" content=" csrf_token() "&gt; 添加到您的 HTML / 布局中,这应该可以解决您的问题。

【讨论】:

以上是关于Laravel echo - 无法通过私有频道进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

laravel-echo-server 404 尝试进行身份验证时

使用 socket.io 和 Laravel Echo 时如何保护私有频道?

带有私有通道的 Laravel Echo SocketIO

无法使用 Redis 和 Laravel 5.3 在私有频道上广播通知

无法使用 Laravel echo server、redis 和 socket.io 验证 laravel 私人频道

Laravel Echo - 允许访客连接到出席频道