You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中channels.php未触发,私有频道权限验证失效问题

使用Soketi+Pusher时channels.php频道验证未触发的问题

我用Soketi结合Pusher实现功能(未使用Echo),能正常向私有频道发送通知,但channels.php里的权限验证逻辑完全没触发——日志没输出,返回true/false也不影响用户订阅频道。


相关代码片段

routes/channels.php

Broadcast::channel('test.{id}', function ($user, $id) 
{
    \Log::debug('testing this endpoint'); // 从未执行
    
    return false; // 也从未执行,返回true或false都无影响
});

config/app.php

'providers' => ServiceProvider::defaultProviders()->merge([
    \hisorange\BrowserDetect\ServiceProvider::class,
    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    App\Providers\BroadcastServiceProvider::class, // <--- 已取消注释该行
    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
])->toArray(),

app/providers/BroadcastServiceProvider.php

class BroadcastServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Broadcast::routes();

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

TestEvent.php

class TestEvent implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct(public string $text)
    {
        //
    }

    public function broadcastOn(): array
    {
        return [
            new PrivateChannel('test.3')
        ];
    }

    public function broadcastAs(): string
    {
        return 'message';
    }
}

Pusher JS配置

const pusher = new Pusher('app-key', 
{
    wsHost: '127.0.0.1',
    wsPort: 6001,
    forceTLS: false,
    encrypted: true,
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
    authEndpoint: 'api/auth',
    auth:
    {
        headers:
        {
            'Authorization': `Bearer ${token}`,
        },
    }
});

const channel = pusher.subscribe('private-test.3');
channel.bind('message', function(message)
{
    console.log(message);
});

测试事件代码

broadcast(new TestEvent('Hello World!'));

实际现象

  • 用户成功连接Pusher/WebSockets
  • 事件发送并接收正常
  • channels.php中的验证逻辑从未触发,broadcast/channel/test.{id}端点完全未被调用

Pusher日志

Pusher : ["State changed","initialized -> connecting"]
Pusher: ["Connecting",{"transport":"ws","url":"ws://127.0.0.1:6001/app/app-key?protocol=7&client=js&version=8.3.0&flash=false"}]
Pusher: ["State changed","connecting -> connected with new socket ID 8035059900.2497835364"]
Pusher: ["Event sent",{"event":"pusher:subscribe","data":{"auth":"app-key:8623bcc00ba6c28dea66645316bd2eb2943aa5c8115f1cac7cede17e4994809a","channel":"private-test.3"}}]
Pusher: ["Event recd",{"event":"pusher_internal:subscription_succeeded","channel":"private-test.3"}]
Pusher: ["No callbacks on private-test.3 for pusher:subscription_succeeded"]
Pusher: ["Event recd",{"event":"message","channel":"private-test.3","data":{"text":"Hello World!"}}]
my-js.js {text: 'Hello World!'}

问题排查与解决方向

  1. Auth端点配置不匹配
    Laravel默认的广播授权端点是/broadcasting/auth,但你的JS里设成了api/auth,如果没有自定义路由指向授权逻辑,Soketi会跳过Laravel验证直接允许订阅。

    • 解决:把JS中的authEndpoint改为/broadcasting/auth,或者确保api/auth路由正确指向Laravel的广播授权处理。
  2. Soketi配置禁用了授权验证
    检查Soketi的配置文件(如soketi.json)或环境变量,如果设置了AUTHENTICATION_DISABLED=true,会直接跳过所有频道的权限验证。

    • 解决:确保Soketi配置中开启授权,设置AUTHENTICATION_ENABLED=true,并保证私有频道需要授权验证。
  3. Broadcast路由前缀问题
    如果你的API使用了前缀,需要在BroadcastServiceProvider中指定前缀:

    Broadcast::routes(['prefix' => 'api']);
    

    此时授权端点会变为/api/broadcasting/auth,需同步修改JS中的authEndpoint。

  4. 认证中间件不匹配
    Laravel默认Broadcast::routes()使用web中间件,如果你用API令牌认证,需要修改中间件组:

    Broadcast::routes(['middleware' => ['auth:api']]);
    

    确保Bearer令牌能被正确解析,获取当前用户。

内容的提问来源于stack exchange,提问作者Linesofcode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:38:14