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

ammar_ahmed's avatar

403 Forbidden on /broadcasting/auth when using Laravel Echo + Pusher

I am implementing real-time broadcasting in Laravel 12 with React (Inertia) using Pusher and Laravel Echo.

The backend event fires successfully, but the frontend does not receive the broadcast. In the browser console, I consistently get the following error:

POST http://127.0.0.1:8000/broadcasting/auth 403 (Forbidden)

1. Route Where the Event Is Fired (web.php)

The event is triggered from a route using the authenticated user.

Route::get('/send-message', function () {
    $userId = auth()->id();
    $message = 'message from ' . auth()->user()->name;

    event(new MessageSent($userId, $message));

    return response()->json(['status' => 'Message sent']);
});

EvnentMessage

Channel.php

Broadcast::channel('chat.{userId}', function ($user, $userId) {
    return true;
});

Chat.tsx

Listening the event

import { SharedData } from '@/types';
import { usePage } from '@inertiajs/react';
import { useEcho } from '@laravel/echo-react';

export default function Chat() {
    const { auth } = usePage<SharedData>().props;
    const userId = auth?.user?.id;

    useEcho(`chat.${userId}`, 'MessageSent', (e) => {
        console.log(e.message);
    });
    return <div>Check console for messages!</div>;
}

App.tsx

import { configureEcho } from '@laravel/echo-react';

configureEcho({
    broadcaster: 'pusher',
});
1 like
1 reply
vincent15000's avatar

You just have to implement authorization for your broadcasting.

import Cookies from 'js-cookie';

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: import.meta.env.VITE_PUSHER_APP_KEY,
    cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
    forceTLS: false,
    encrypted: false,
    channelAuthorization: {
        endpoint: '/api/broadcasting/auth',
        headers: {
            'X-XSRF-TOKEN': Cookies.get('XSRF-TOKEN'),
            Accept: 'application/json',
        },
    },
});

You also have to add a line in the bootstrap/app.php file.

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api_v1.php',
        commands: __DIR__.'/../routes/console.php',
        channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->statefulApi();
        $middleware->alias([
            'shared.datas' => SharedDatasMiddleware::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions): void {
        //
    })
    ->withBroadcasting(
        __DIR__.'/../routes/channels.php',
        ['prefix' => 'api', 'middleware' => ['api', 'auth:sanctum']],
    )
    ->create();

Please or to participate in this conversation.