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 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. Hoe providers worden geladen, lees je bij automatische package-discovery.
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
falseterug, dan wordt direct eenAccessDeniedHttpExceptiongegooid. - Geeft een callback een ware waarde zoals
trueterug, dan is de autorisatie op dat moment geslaagd. - Geeft een callback een onware waarde zoals
nullterug, dan gaat de evaluatie door naar de volgende geregistreerde callback. Laat geen enkele callback toe, dan wordt aan het eind eenAccessDeniedHttpExceptiongegooid.
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 packageAcme\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.
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.
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 aanwithBroadcasting() 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.
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.
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.
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 alsCollection met getChannels() van de driver. De sleutels zijn de kanaalnamen zelf.
/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.
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
Containergeresolved. Gebruik voor constructorafhankelijkheden types die de container kan resolven.
Samenvatting
De kanaalautorisatie van een package werkt zodra jeBroadcast::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.