Laravel Echo+Lighthouse订阅遇403错误:Vue3与Laravel API集成问题
问题:Vue3 + Laravel API 环境中 Laravel Echo 订阅/广播触发403错误
问题背景
普通GraphQL查询可正常执行,但执行GraphQL订阅或监听Laravel广播事件时,触发403禁止错误。
前端配置
const httpLink = new HttpLink({ uri: import.meta.env.VITE_APP_GRAPHQL_URL, }); const echo = new Echo({ broadcaster: 'pusher', key: import.meta.env.VITE_PUSHER_APP_KEY.toString(), cluster: 'eu', forceTLS: true, disableStats: true, authEndpoint: import.meta.env.VITE_APP_GRAPHQL_URL + `/subscriptions/auth`, auth: { headers: { Accept: 'application/json', Authorization: 'Bearer ' + CookieManager.get(import.meta.env.VITE_APP_ID_TOKEN_COOKIE?.toString() ?? '') ?? undefined, }, }, }); export const apolloClient = new ApolloClient({ link: from([errorLink, authLink, httpLink]), cache: new InMemoryCache(), }); export const subscriptionClient = new ApolloClient({ link: from([authLink, createLighthouseSubscriptionLink(echo), httpLink]), cache: new InMemoryCache(), });
配置已在main.ts中载入:
app.provide(DefaultApolloClient, subscriptionClient);
测试场景
- 创建TestEvent事件
<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class TestEvent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public function __construct() { } public function broadcastOn(): Channel { return new PrivateChannel('test'); } }
- 创建测试频道
Broadcast::channel('test', function ($user) { return true; });
- 前端监听频道
echo.private('test').listen('TestEvent', (e) => { console.log(e); });
错误信息
Pusher : : ["Error: Unable to retrieve auth string from channel-authorization endpoint - received status: 403 from http://localhost:8000/graphql/subscriptions/auth. Clients must be authenticated to join private or presence channels. See: https://pusher.com/docs/channels/server_api/authorizing-users/"]
排查与解决方法
1. 认证端点路由与服务配置
- 确认
BroadcastServiceProvider已在config/app.php的providers数组中注册。 - 检查Lighthouse的订阅认证路由是否正确启用,确保
routes/api.php中包含Lighthouse的路由(通常通过Route::graphql()注册),且/graphql/subscriptions/auth可被正常访问。
2. 前端认证头有效性
- 在浏览器Network面板中查看
/graphql/subscriptions/auth请求的请求头,确认Authorization头携带了有效的Bearer Token,避免出现Bearer undefined的情况。优化前端认证头代码:Authorization: CookieManager.get(import.meta.env.VITE_APP_ID_TOKEN_COOKIE?.toString() ?? '') ? `Bearer ${CookieManager.get(import.meta.env.VITE_APP_ID_TOKEN_COOKIE?.toString() ?? '')}` : undefined,
3. CORS配置检查
- 确保
config/cors.php中allowed_headers包含Authorization,supports_credentials设置为true(若依赖Cookie传递Token),且allowed_origins包含前端域名。
4. 广播认证逻辑验证
- 在频道回调中添加日志,确认当前请求的
$user对象是否存在:Broadcast::channel('test', function ($user) { \Log::info('Broadcast auth user:', [$user]); return true; }); - 若API使用自定义认证guard,需在
config/lighthouse.php中配置对应guard:'subscriptions' => [ 'auth' => [ 'guard' => 'api', // 替换为你的认证guard名称 ], ],
5. Pusher配置一致性
- 确认前端Pusher的
key、cluster与Laravel.env中的PUSHER_APP_KEY、PUSHER_APP_CLUSTER完全一致。 - 本地开发若未使用HTTPS,将
forceTLS设为false,避免请求协议不匹配。
内容的提问来源于stack exchange,提问作者niels van hoof
相关产品推荐
相关产品推荐

