In this episode, we tackle the tricky problem of authenticating WebSocket connections from a single-page app (SPA) using Laravel Echo, especially when dealing with private channels and Laravel Sanctum.
First, we realize that Laravel Echo tries to authenticate WebSocket connections by hitting a default endpoint that matches the client's origin, which isn't correct in a typical dev setup (like localhost:3000 for the frontend and another port for the API backend). We walk through how to override Echo's default authorizer so it can correctly reach our API's broadcasting auth endpoint, sending the necessary socket ID and channel name for authentication.
You'll see step-by-step how to send off a request using our existing Sanctum setup, making sure things like CSRF tokens are included for proper security. There’s a little config tweak to ensure the request is POSTed to the right auth endpoint and that the request body contains exactly the data Laravel’s broadcaster expects.
But of course, things aren't quite done yet! We run into CORS (cross-origin resource sharing) issues, which we solve by ensuring the broadcasting routes are prefixed with /api
and use Sanctum and API middleware. This makes sure our auth requests are handled the same way as our other API requests and gets rid of those pesky CORS errors.
After getting everything setup in both the backend and frontend, we confirm that we can now connect to private channels and get the expected auth token back. We test both success and failure cases (including when access is denied), and explain how the callback system lets Echo know if we’re authorized or not.
By the end, we’ve got a smooth SPA WebSocket authentication flow via Sanctum, and your app is ready to securely use private event channels via Laravel Echo. Any new private channels you add will 'just work' with this setup!