Я знаю, что я не первый борюсь с этим. Но после нескольких дней, когда я задавал множество связанных вопросов, я почему-то чувствую, что мой случай заслуживает отдельного вопроса :).
У меня есть рабочие решения для веб-сокетов с Laravel Websockets (https://beyondco.de/docs/laravel-websockets/getting-started/introduction) и Laravel Echo для общедоступных каналов. Мое клиентское приложение представляет собой приложение vue-cli и подключается к серверу + широковещательные сообщения по общедоступным каналам отлично работают. Авторизация осуществляется Laravel Passport. Таким образом, отправляя токен-носитель в заголовке авторизации, серверное приложение знает, аутентифицирован ли пользователь.
Однако я изо всех сил пытаюсь заставить работать частные каналы. Попытка аутентификации всегда дает мне эту ошибку:
Access to XMLHttpRequest at 'https://my-app.test/broadcasting/auth' from origin 'https://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Я знаю, что эта ошибка CORS возникает у меня, когда у меня возникают проблемы с сервером, поэтому я попытался отладить запрос в Insomnia. Однако при имитации запроса в Insomnia он дает ответ 200, а также то, что можно было бы ожидать:
Я читал несколько руководств и вопросы о stackoverflow, но не могу найти ничего похожего. Возвращение к этому может быть связано с проблемами CORS, но я не думаю, что это так. Мой запрос OPTIONS возвращается в нормальном состоянии.
Для полноты я также добавляю код, который может помочь в отладке.
Мой BroadcastServiceProvider
public function boot()
{
Broadcast::routes(['middleware' => ['auth:api']]);
require base_path('routes/channels.php');
}
Мои каналы .php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Клиент
this.echoClient = new Echo({
broadcaster: 'pusher',
key: process.env.VUE_APP_WEBSOCKETS_APP_ID,
wsHost: process.env.VUE_APP_WEBSOCKETS_URL,
wssPort: 6001,
// forceTLS: true,
disableStats: true,
authEndpoint: process.env.VUE_APP_SERVER_URL + '/broadcasting/auth',
auth: {
headers: {
Authorization: "Bearer " + this.$store.state.auth.auth_token
}
}
})
// this one works!!
this.echoClient.channel('App.User')
.listen('UpdatePosts', (e) => {
console.log('event received')
console.log(e)
})
// private channels don't work ... :'(
this.echoClient.private('App.User.' + this.user.id)
.listen('UpdatePosts', function(e) {
console.log(e)
})