Имеется приложение с перепиской между пользователями и возможностью публиковать статьи
в реальном времени (на websocket). Приложение
SPA, имеется Laravel Passport аутентификация через
токен, соответственно к каждому запросу в заголовке должен быть
прикреплен токен.
При авторизации в
VUEX вызывается мутация, которая сохраняет токен
в локальном хранилище и изменяет состояние вошел ли пользователь в систему. (
state.isLoggedIn)
loginUser(state, data) {
state.isLoggedIn = true;
localStorage.setItem('token', data.access_token);
},
Для обычных axios запросов через интерсепторы добавляется заголовок с токеном к каждому запросу:
axios.interceptors.request.use(function (config) {
config.headers.Authorization = 'Bearer ' + localStorage.getItem('token');
return config;
}, function (err) {
return Promise.reject(err);
});
В файле app.js настройки laravel-echo-server:
import Echo from "laravel-echo"
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001',
auth: {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
},
},
});
В
BroadcastServiceProvider:
Broadcast::routes(['middleware' => ['auth:api']]);
Соответственно, если пользователь авторизуется впервые, у него еще нет в хранилище
localStorage.getItem('token') и сервер его не пропустит (Придется обновлять страницу).
Экземпляр vue создается вот так:
const app = new Vue({
el: '#app',
router,
store,
components: {
MainApp
},
});
Есть идея создать watcher в
MainApp vue-компоненте который следит за состоянием в vuex (
state.isLoggedIn) и после этого там вызывать код с настройками laravel-echo-server, правда немного не понимаю как это реализовать. Может быть есть еще какой-либо способ?
Update: На данный момент удалось реализовать вот так, может быть есть способ без использования watcher?
watch: {
isLoggedIn: function (val) {
if (val === true) {
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001',
auth: {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
},
},
});
window.Echo.private('room.' + this.user_id)
.listen('PrivateChat', ({data}) => {
...
}
})
}
}
}