返回

在 Vue 3 和 Laravel Sanctum 中如何授权广播路由?

vue.js

在 Vue 3 和 Laravel Sanctum 中授权广播路由

问题

在使用 Vue 3 单页面应用和 Laravel Sanctum 后端设置私有频道广播时,访问需要 Sanctum 保护的路由(私有频道需要)时会向客户端返回 401。

解决方案

为了解决此问题,需要授权广播路由以允许受 Sanctum 保护的客户端访问。以下是授权广播路由的步骤:

后端设置:

  1. /routes/api.php 中,确保广播授权路由已使用 auth:sanctum 中间件保护。
  2. 创建一个自定义广播频道,将用户与频道关联。
  3. BroadcastServiceProvider.php 中,将自定义频道添加到广播配置中。

前端设置:

  1. 使用 Axios 获取 CSRF 令牌,并将其添加到广播连接标头中。
  2. 创建一个带有授权令牌的 Laravel Echo 实例。
  3. 使用 Echo 实例订阅私有频道并侦听广播事件。

示例代码

后端:

// /routes/api.php
Route::middleware('auth:sanctum')->group(function () {
    Route::post('/broadcasting/auth', function (Request $request) {
        return response()->json(['success' => true]);
    });
});

// /app/Events/ChatMessageSent.php
class ChatMessageSent implements ShouldBroadcast
{
    public function broadcastOn()
    {
        return new PrivateChannel('chat.'.$this->chatSessionId);
    }
}

// /routes/channels.php
Broadcast::channel('chat.{chatSessionId}', function ($user, $chatSessionId) {
    // 检查用户是否为聊天会话的参与者
    return true;
});

前端:

// /chat.vue
import initEcho from '@/lib/laravel-echo.js'

const createEchoInstance = () => {
  const echo = initEcho(store.authToken);

  echo.private(`private-chat.${state.chatSessionId}`).listen('ChatMessageSent', (data) => {
    // 处理广播事件
  });
};

常见问题解答

1. 为什么需要授权广播路由?

授权广播路由可确保只有授权用户才能访问受保护的私有频道。

2. 如何获取 CSRF 令牌?

可以使用 Axios 通过 GET 请求获取 CSRF 令牌:

axios.get('/sanctum/csrf-cookie').then((res) => {
  // 使用 res.config.headers['X-XSRF-TOKEN'] 作为 CSRF 令牌
});

3. 如何创建带有授权令牌的 Laravel Echo 实例?

可以使用 Laravel Echo 实例化器创建带有授权令牌的 Laravel Echo 实例:

const echo = new Echo({
  // 其他配置选项...
  auth: {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  },
});

4. 如何订阅私有频道并侦听广播事件?

可以使用 Laravel Echo 的 private 方法订阅私有频道并侦听广播事件:

echo.private(`private-chat.${state.chatSessionId}`).listen('ChatMessageSent', (data) => {
  // 处理广播事件
});

5. 如何确保只有授权用户才能访问私有频道?

在广播频道中实现授权逻辑,例如检查用户是否为聊天会话的参与者。