laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.31k stars 10.95k forks source link

Broadcasting does not work #50754

Closed martinbean closed 6 months ago

martinbean commented 6 months ago

Laravel Version

11.0.8

PHP Version

8.3.3

Database Driver & Version

No response

Description

I’m trying to install broadcasting but it does not seem to register the /broadcasting/auth route anywhere, so private channels are not getting authorised.

Steps To Reproduce

  1. Run php artisan install:broadcasting
  2. Run composer require pusher/pusher-php-server
  3. Add ShouldBroadcast interface to event, and define broadcastOn method
  4. Events are dispatched to Pusher, as I can see them arrive in the debug console
  5. Listening to channels does not work, as requests for POST /broadcasting/auth receive a 404 Not Found response

The Laravel broadcasting docs state:

When broadcasting is enabled, Laravel automatically registers the /broadcasting/auth route to handle authorization requests.

But this does not seem to be happening in practice.

crynobone commented 6 months ago

Hey there, thanks for reporting this issue.

We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here?

Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.

laravel new bug-report --github="--public"

Do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.

Thanks!

martinbean commented 6 months ago

We'll need more info and/or code to debug this further.

@crynobone I outlined the steps in my initial post. I’m afraid I can’t use the Laravel Installer as I don’t have Composer installed on my machine, so can’t install global Composer packages. such as that.

It’s a relatively new Laravel 11 application. Installed Broadcasting as per the Laravel docs. Broadcasting authorisation route (/broadcasting/auth) is not registered. Confirmed by running php artisan route:list and the authorisation route not being listed there. So the authorisation route is not registered “automatically” despite the Laravel docs saying it will be.

crynobone commented 6 months ago

Can you share the content of bootstrap/app.php?

martinbean commented 6 months ago

Can you share the content of bootstrap/app.php?

Sure:

<?php

use App\Http\Middleware\HandleRedirects;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

return Application::configure(basePath: dirname(__DIR__))
    ->withExceptions(function (Exceptions $exceptions): void {
        //
    })
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->alias([
            'features' => \Laravel\Pennant\Middleware\EnsureFeaturesAreActive::class,
        ]);

        $middleware->append(HandleRedirects::class);

        $middleware->group('web.channel', [
            \App\Http\Middleware\SetChannelViewNamespace::class,
        ]);

        $middleware->group('web.channel.admin', [
            \App\Http\Middleware\HandleInertiaRequests::class,
        ]);

        $middleware->trustProxies(
            at: '*',
            headers: Request::HEADER_X_FORWARDED_AWS_ELB,
        );

        $middleware->validateCsrfTokens(except: [
            'mux/webhook',
            'stripe/*',
        ]);
    })
    ->withRouting(
        health: '/up',
        web: __DIR__ . '/../routes/web.php',
        then: function (): void {
            // Channel
            Route::middleware('web', 'web.channel', 'can:view,channel')
                ->name('channel.')
                ->prefix('channels/{channel:slug}')
                ->group(base_path('routes/web.channel.php'));

            // Channel Admin
            Route::middleware('web', 'auth', 'can:update,channel', 'web.channel.admin')
                ->name('channel.admin.')
                ->prefix('channels/{channel:slug}/admin')
                ->group(base_path('routes/web.channel.admin.php'));
        },
    )
    ->create();
crynobone commented 6 months ago

You're missing channels https://github.com/laravel/framework/blob/efa867e85b4abcaab8146f66bc676b7239507719/src/Illuminate/Foundation/Configuration/ApplicationBuilder.php#L163 which should be added via the install command. Missing that would prevent the default behaviour.

martinbean commented 6 months ago

You're missing channels

That channels key doesn’t exist in the Laravel 11.x skeleton, though?

https://github.com/laravel/laravel/blob/441845d88dfc2a4fbf59f1e57d48889c8de664bb/bootstrap/app.php#L8-L11

crynobone commented 6 months ago

See https://github.com/laravel/framework/blob/efa867e85b4abcaab8146f66bc676b7239507719/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php#L88

martinbean commented 6 months ago

@crynobone Yes, all of those conditions will evaluate as false in my case. I removed the commands file as I detest using a “routes” file to register Artisan commands.

crynobone commented 6 months ago

In that case, you should either use withBroadcasting() method or register the route manually.

thecyrilcril commented 1 month ago

I am having the same issue. here is my bootstrap/app.php file

<?php

declare(strict_types=1);

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {})
    ->withExceptions(function (Exceptions $exceptions): void {})->create();

Manually adding channels: __DIR__ . '/../routes/channels.php', to the withRouting method seems to fix it but I think this might be a bug on Windows as am always running into it

martinbean commented 1 month ago

@thecyrilcril I got around it by adding the broadcasting routes and channel definitions to my AppServiceProvider file:

use Illuminate\Support\Facades\Broadcast;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Broadcast::routes();

        Broadcast::channel('orders.{order}', function (User $user, Order $order): bool {
            return $order->user()->is($user);
        }
    }
}