> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Autorisatie en overschrijven van broadcastkanalen in packages

> Legt uit in welke volgorde de autorisatie wordt geëvalueerd wanneer een package privékanalen registreert, hoe de gebruikende applicatie die kan overschrijven en hoe je dit met HTTP-tests controleert.

Wanneer een package realtime events uitzendt, ontwerp je de **definitie van de kanaalnaam** en de **controle wie mag meedoen** los van elkaar. Een kanaal dat het package in `boot()` registreert, kan worden overschreven als de `routes/channels.php` van de gebruikende applicatie dezelfde naam gebruikt. Als je deze registratie- en evaluatievolgorde begrijpt, voorkom je bugs tijdens onderhoud.

Deze pagina verwijst naar de officiële Laravel-documentatie over [broadcasting](https://kawax.biz/nl/broadcasting.md) en naar de implementatie van de nieuwste release `v13.42.0` die voor de controle is gebruikt. Hoe je events verstuurt, lees je bij [broadcasting](https://kawax.biz/nl/broadcasting.md). Hoe providers worden geladen, lees je bij [automatische package-discovery](https://kawax.biz/nl/advanced/package-discovery.md).

## Hoe kanaalautorisatie werkt

Wanneer een client zich abonneert op een privékanaal, stuurt hij een request naar `/broadcasting/auth`. `BroadcastController::authenticate()` geeft de verwerking door aan `Broadcast::auth()`, en de `Broadcaster` evalueert de geregistreerde callbacks op volgorde.

De evaluatieregels zijn als volgt:

* Geeft een callback `false` terug, dan wordt direct een `AccessDeniedHttpException` gegooid.
* Geeft een callback een ware waarde zoals `true` terug, dan is de autorisatie op dat moment geslaagd.
* Geeft een callback een onware waarde zoals `null` terug, dan gaat de evaluatie door naar de volgende geregistreerde callback. Laat geen enkele callback toe, dan wordt aan het eind een `AccessDeniedHttpException` gegooid.

> [!NOTE]
>
> De drivers `Pusher` en `Reverb` verwijderen vóór de autorisatie de prefixen `private-` en `presence-`. Neem het prefix daarom niet op in de kanaalnamen die je registreert.

## Een kanaal registreren in een package

Als voorbeeld zendt een fictief package `Acme\Orders` statuswijzigingen van bestellingen uit. De kanaalnaam is `acme.orders.{order}`, en alleen de eigenaar van de bestelling mag zich abonneren.

Roep in de `ServiceProvider` van het package `Broadcast::channel()` aan binnen `boot()`. De controle delegeer je naar een klasse in het package.

```php theme={null}
use Acme\Orders\Broadcasting\OrderChannel;
use Illuminate\Support\Facades\Broadcast;

public function boot(): void
{
    Broadcast::channel('acme.orders.{order}', OrderChannel::class);
}
```

```php theme={null}
<?php

namespace Acme\Orders\Broadcasting;

use Acme\Orders\Models\Order;
use Illuminate\Contracts\Auth\Authenticatable;

class OrderChannel
{
    public function join(Authenticatable $user, Order $order): bool
    {
        return $user->getAuthIdentifier() === $order->owner_id;
    }
}
```

Het eerste argument van `join()` krijgt de gebruiker op het moment van autorisatie. De volgende argumenten krijgen de waarden van de `{...}` in de kanaalnaam. Komt de parameternaam `{order}` overeen met `Order $order` en is het type een subklasse van `UrlRoutable`, dan werkt route model binding.

> [!NOTE]
>
> Als `$callback` van `Broadcast::channel()` kun je een `callable` opgeven of de naam van een klasse met een `join()`-methode. Bij een klassenaam maakt `Broadcaster::normalizeChannelHandlerToCallable()` de instantie aan via de container en roept daarna `join()` aan.

## Overschrijven door de gebruikende applicatie

Het bestand dat de gebruikende applicatie aan `withBroadcasting()` doorgeeft (meestal `routes/channels.php`), wordt geladen in een `booted`-callback die `withBroadcasting()` registreert. `booted`-callbacks draaien pas nadat `boot()` van alle service providers klaar is, dus de registratie in `boot()` van het package gebeurt eerst.

| Volgorde | Verwerking | Wat wordt geregistreerd |
| - | - | - |
| 1 | `boot()` van het package | De callback voor `acme.orders.{order}` |
| 2 | Routes laden in de `booted` van de applicatie | De callback uit `routes/channels.php` |

`Broadcaster::channel()` slaat callbacks op in een interne array met de kanaalnaam als sleutel. Registreert de gebruikende applicatie dezelfde naam, dan vervangt de tweede registratie die van het package. Laravel behandelt een dubbele naam niet als fout.

Om overschrijven te voorkomen, maak je de kanaalnaam uniek. Met een package-specifiek prefix zoals in `acme.orders.{order}` wordt de kans kleiner dat de gebruikende applicatie dezelfde naam registreert.
De kanaalnaam is een publiek contract met de clients. Verander hem niet meer nadat je hem hebt gekozen. Als je hem verandert, kunnen oude clients zich niet meer abonneren.

> [!WARNING]
>
> Bij kanalen met dezelfde naam krijgt de later geregistreerde stilzwijgend voorrang. `php artisan channel:list` toont de kanaalnaam en het resolutiedoel (klassenaam of `Closure`), zodat je kunt controleren welke registratie overblijft.

## Kanaalopties en guards

Het derde argument `$options` van `Broadcast::channel()` wordt opgeslagen als configuratie per kanaal. Geef je `guards` op, dan worden de guards voor authenticatie op volgorde geprobeerd.

```php theme={null}
Broadcast::channel('acme.orders.{order}', OrderChannel::class, [
    'guards' => ['web', 'api'],
]);
```

Laat je `guards` weg, dan wordt de standaardgebruiker van de request (`$request->user()`) voor de autorisatie gebruikt. Geef je `guards` op, dan wordt `$request->user($guard)` van voor naar achter aangeroepen en wordt de eerst gevonden gebruiker gebruikt. Als het package de guardnamen niet vastlegt maar als configuratiewaarde aanbiedt, kan de gebruikende applicatie ze kiezen.

## De kanaalregistratie controleren in tests

Geregistreerde kanalen haal je op als `Collection` met `getChannels()` van de driver. De sleutels zijn de kanaalnamen zelf.

```php theme={null}
use Illuminate\Support\Facades\Broadcast;

public function test_package_registers_order_channel(): void
{
    $channels = Broadcast::driver()->getChannels();

    $this->assertTrue($channels->has('acme.orders.{order}'));
}
```

Het resultaat van de autorisatie controleer je met een HTTP-test op `/broadcasting/auth`. De drivers `null` en `log` geven niets terug uit `auth()`, dus die kun je voor deze test niet gebruiken. Kanalen worden bij het opstarten van de applicatie bij de standaarddriver geregistreerd. Zet daarom `BROADCAST_CONNECTION` op `reverb` of `pusher`, bijvoorbeeld in de `phpunit.xml` voor tests, voordat je de geauthenticeerde request verstuurt.

```php theme={null}
use Acme\Orders\Models\Order;
use App\Models\User;

public function test_owner_can_join_order_channel(): void
{
    $user = User::factory()->create();
    $order = Order::factory()->for($user, 'owner')->create();

    $this->actingAs($user)
        ->post('/broadcasting/auth', [
            'channel_name' => 'private-acme.orders.'.$order->id,
            'socket_id' => '1234.5678',
        ])
        ->assertOk();
}
```

> [!TIP]
>
> In de testapp moet `/broadcasting/auth` geregistreerd zijn. Deze route wordt geregistreerd door `Broadcast::routes()`, en `BroadcastManager::channelRoutes()` geeft dezelfde verwerking alleen door aan `routes()`. Zijn de routes gecachet, dan doet `routes()` niets.

## Aandachtspunten bij onderhoud

* Kanaalnamen zijn een publiek contract. Als je een naam verandert, kunnen bestaande clients zich niet meer abonneren.
* Klassegebaseerde kanalen worden via de `Container` geresolved. Gebruik voor constructorafhankelijkheden types die de container kan resolven.

## Samenvatting

De kanaalautorisatie van een package werkt zodra je `Broadcast::channel()` in `boot()` registreert. Registreert de `routes/channels.php` van de gebruikende applicatie later dezelfde naam, dan wordt de autorisatie van het package vervangen. Een prefix in de kanaalnaam, de controle in een aparte klasse en HTTP-tests voor het resultaat van `/broadcasting/auth` maken het package beter onderhoudbaar.

## Geraadpleegde primaire bronnen

* [Officiële Laravel-documentatie: broadcasting](https://github.com/laravel/docs/blob/13.x/broadcasting.md)
* [Framework v13.42.0: Broadcaster](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php)
* [Framework v13.42.0: UsePusherChannelConventions](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Broadcasting/Broadcasters/UsePusherChannelConventions.php)
* [Framework v13.42.0: BroadcastManager](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Broadcasting/BroadcastManager.php)
* [Framework v13.42.0: ApplicationBuilder](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Foundation/Configuration/ApplicationBuilder.php)
* [Framework v13.42.0: BroadcastController](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Broadcasting/BroadcastController.php)
* [Framework v13.42.0: commando channel:list](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Foundation/Console/ChannelListCommand.php)


## Related topics

- [Views van packages overschrijven en bijwerken](https://kawax.biz/nl/advanced/package-views.md)
- [Policies registreren en overschrijven in packages](https://kawax.biz/nl/advanced/package-authorization.md)
- [Autorisatie (gates en policies)](https://kawax.biz/nl/authorization.md)
- [Packagevertalingen overschrijven en bijwerken](https://kawax.biz/nl/advanced/package-translations.md)
- [Middleware van packages registreren en het toepassingsbereik](https://kawax.biz/nl/advanced/package-middleware.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.