Vue3/Laravel集成Pusher私有频道Sanctum授权401问题
Pusher私有频道Sanctum授权401问题排查与解决
问题核心
非私有频道正常工作,但订阅私有频道时,Pusher发起的/api/pusher/auth请求返回401,且请求未携带已有的认证Cookie,导致$request->user()为空,其他API路由则能正常获取用户信息。
解决步骤
1. 前端配置修复
Pusher的授权请求需要携带X-XSRF-TOKEN头才能通过Sanctum验证,当前配置缺少该头信息。修改pusher.js:
import Pusher from 'pusher-js' Pusher.logToConsole = true // 从Cookie中提取XSRF-TOKEN const getXsrfToken = () => { const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/) return match ? decodeURIComponent(match[1]) : '' } const pusher = new Pusher('bf29be46d8eb2ea8ccd4', { cluster: 'eu', forceTLS: true, authEndpoint: 'http://localhost:8000/api/pusher/auth', withCredentials: true, wsPort: 443, wssPort: 443, enableStats: false, enabledTransports: ['ws', 'wss'], auth: { headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-XSRF-TOKEN': getXsrfToken() // 添加XSRF Token头 }, } }) export default pusher
2. 后端CORS配置检查
确保跨域请求允许携带凭证,修改config/cors.php:
return [ 'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout', 'api/pusher/auth'], 'allowed_methods' => ['*'], 'allowed_origins' => [env('FRONTEND_URL')], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, // 必须设为true,允许携带Cookie ];
3. 后端路由调试
临时移除auth:sanctum中间件,打印请求信息确认是否收到Cookie:
Route::post('/pusher/auth', function (Request $request) { \Log::info('请求Cookie:', $request->cookies->all()); \Log::info('请求Headers:', $request->headers->all()); $user = $request->user(); if (!$user) { abort(403, 'Unauthorized'); } $pusher = new Pusher( env('PUSHER_APP_KEY'), env('PUSHER_APP_SECRET'), env('PUSHER_APP_ID'), ['cluster' => env('PUSHER_APP_CLUSTER')] ); $channelName = $request->channel_name; $socketId = $request->socket_id; $auth = $pusher->socket_auth($channelName, $socketId); return response()->json(['auth' => $auth]); });
查看storage/logs/laravel.log,如果日志中没有soul_meatcom_session和XSRF-TOKEN,说明前端请求未正确携带Cookie,需检查:
- 浏览器中Cookie的Domain是否为
localhost,Path是否为/ - 前端
withCredentials是否全局开启(当前axios已配置,Pusher也已设置)
4. 环境变量验证
确认.env中以下配置无误:
SANCTUM_STATEFUL_DOMAINS=localhost:3000 SESSION_DOMAIN=localhost FRONTEND_URL=http://localhost:3000
关键注意点
- 跨域请求携带Cookie必须同时满足:前端
withCredentials=true,后端supports_credentials=true,且Access-Control-Allow-Origin不能为*(需指定具体域名) - Sanctum依赖
X-XSRF-TOKEN头和session Cookie完成认证,二者缺一不可
内容的提问来源于stack exchange,提问作者Artur Müller Romanov
相关产品推荐
相关产品推荐

