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

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);

测试场景

  1. 创建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');
    }
}
  1. 创建测试频道
Broadcast::channel('test', function ($user) {
    return true;
});
  1. 前端监听频道
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:40:50