Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

HenrijsS's avatar

[Echo] Resubscribe to events when Bearer token is available.

Hey.

Our setup is Laravel Reverb, headless Vue 3 and for auth we use Amazon Cognito. The app is private and all Broadcast channels are private.

When the page loads, the bearer token is not yet available as I'm just sending the Cognito auth code to my backend and only then I get the bearer token. The problem is that Echo already loads and fails the auth which I don't see how to retry. What I'm doing now is that when the bearerToken is available, I reconnect the channel.

The problem is that it loses all connections and listeners to the events.

What's the correct way to use it? The documentation for Echo doesn't exist, so I was going through the code itself.

useEcho.ts

auth.ts

    checkIfTokenIsStored() {
      const token = localStorage.getItem("accessToken");

      if (token) {
        useHttp.defaults.headers.common.Authorization = `Bearer ${token}`;
        this.isAuthenticated = true;

        if (!this.isEchoAuthenticated) {
          reconnectEcho(token);
          this.isEchoAuthenticated = true;
        }
      }
    },

Notifications.vue

useEcho
  .private(`user-notifications.${userStore.user.id}`)
  .on("notification-downloaded", (event: { notification: Notification }) => {
    toast.success(event.notification.title, {
      description: event.notification.message,
    });

    notifications.value.unshift(event.notification);
  })
  .on("notification-error", (event: { notification: Notification }) => {
    toast.error(event.notification.title, {
      description: event.notification.message,
    });

    notifications.value.unshift(event.notification);
  });
0 likes
1 reply
Niush's avatar

Well there are multiple ways to do this.

One approach might be to, create a global shared state. Like this:

// src/store/auth.js

const token = ref(null);

export function useAuth() {
  const isAuthenticated = computed(() => !!token.value);

  const setToken = (newToken) => token.value = newToken;

  const clearToken = () => token.vaue = null;

  return { token, isAuthenticated, setToken, clearToken };
}

Then whenever accessToken is available. Set it via useAuth(). Or use something like Pinia.


const { setToken } = useAuth();
// ...
setToken(localStorage.getItem("accessToken"));

Then in Notification.vue you can watch for isAuthenticated and listen or leave a channel. Like:

const { isAuthenticated } = useAuth();

watch(isAuthenticated, () => {
    if (isAuthenticated) {
        listenForNotifications(...); // useEcho.private(...).on...
    }
    else {
        leaveChannel(); // useEcho.leave(...)
    }
});

Another alternative way is using event emitters and listeners. Something like mitt. Example:

const emitter = mitt()

// From auth.ts
emitter.emit('authenticated', { "token": token })

// From Notifications.vue and other components
emitter.on('authenticated', (e) => {
    if (e.token) {
        listenForNotifications(...); // useEcho.private(...).on...
    }
});

Please or to participate in this conversation.