boot() registriert, kann überschrieben werden, wenn die routes/channels.php der nutzenden Anwendung denselben Namen verwendet. Wer diese Registrierungs- und Auswertungsreihenfolge versteht, vermeidet Fehler bei der Wartung.
Diese Seite stützt sich auf die offizielle Laravel-Dokumentation zu Broadcasting und auf die Implementierung des neuesten Releases v13.42.0, das zur Überprüfung verwendet wurde. Wie Sie Events senden, erfahren Sie unter Broadcasting. Wie Provider geladen werden, erfahren Sie unter Paket-Auto-Discovery.
So funktioniert die Kanal-Autorisierung
Wenn ein Client einen privaten Kanal abonniert, sendet er einen Request an/broadcasting/auth. BroadcastController::authenticate() übergibt die Verarbeitung an Broadcast::auth(), und der Broadcaster wertet die registrierten Callbacks der Reihe nach aus.
Für die Auswertung gelten folgende Regeln:
- Gibt ein Callback
falsezurück, wird sofort eineAccessDeniedHttpExceptiongeworfen. - Gibt ein Callback einen wahren Wert wie
truezurück, ist die Autorisierung an dieser Stelle erfolgreich. - Gibt ein Callback einen falschen Wert wie
nullzurück, geht es mit dem nächsten registrierten Callback weiter. Gewährt keiner den Zugriff, wird am Ende eineAccessDeniedHttpExceptiongeworfen.
Die Treiber
Pusher und Reverb entfernen vor der Autorisierung die Präfixe private- und presence-. Nehmen Sie das Präfix deshalb nicht in die registrierten Kanalnamen auf.Einen Kanal im Paket registrieren
Als Beispiel sendet ein fiktives PaketAcme\Orders Statusänderungen von Bestellungen. Der Kanalname lautet acme.orders.{order}, und nur der Eigentümer der Bestellung darf ihn abonnieren.
Rufen Sie im ServiceProvider des Pakets Broadcast::channel() innerhalb von boot() auf. Die Prüfung delegieren Sie an eine Klasse im Paket.
join() erhält den Benutzer zum Zeitpunkt der Autorisierung. Die weiteren Argumente erhalten die Werte der {...}-Platzhalter im Kanalnamen. Stimmt der Parametername {order} mit Order $order überein und ist der Typ eine Unterklasse von UrlRoutable, greift das Route Model Binding.
Als
$callback von Broadcast::channel() können Sie ein callable oder den Namen einer Klasse mit einer join()-Methode angeben. Bei einem Klassennamen erzeugt Broadcaster::normalizeChannelHandlerToCallable() die Instanz über den Container und ruft anschließend join() auf.Überschreiben durch die nutzende Anwendung
Die Datei, die die nutzende Anwendung anwithBroadcasting() übergibt (normalerweise routes/channels.php), wird in einem booted-Callback geladen, den withBroadcasting() registriert. booted-Callbacks laufen erst, nachdem boot() aller Service Provider abgeschlossen ist. Die Registrierung in boot() des Pakets erfolgt daher zuerst.
Broadcaster::channel() speichert die Callbacks in einem internen Array mit dem Kanalnamen als Schlüssel. Registriert die nutzende Anwendung denselben Namen, ersetzt die zweite Registrierung die des Pakets. Laravel meldet einen doppelten Namen nicht als Fehler.
Um ein Überschreiben zu verhindern, machen Sie den Kanalnamen eindeutig. Mit einem paketspezifischen Präfix wie in acme.orders.{order} sinkt die Wahrscheinlichkeit, dass die nutzende Anwendung denselben Namen registriert.
Der Kanalname ist ein öffentlicher Vertrag mit den Clients. Ändern Sie ihn nicht mehr, nachdem Sie ihn festgelegt haben. Eine Änderung führt dazu, dass ältere Clients den Kanal nicht mehr abonnieren können.
Kanaloptionen und Guards
Das dritte Argument$options von Broadcast::channel() wird als kanalspezifische Konfiguration gespeichert. Wenn Sie guards angeben, werden die Guards für die Authentifizierung der Reihe nach ausprobiert.
guards wird der Standardbenutzer des Requests ($request->user()) für die Autorisierung verwendet. Mit guards wird $request->user($guard) der Reihe nach von vorne aufgerufen, und der erste gefundene Benutzer wird verwendet. Wenn das Paket die Guard-Namen nicht fest vorgibt, sondern als Konfigurationswert bereitstellt, kann die nutzende Anwendung sie wählen.
Die Kanalregistrierung in Tests prüfen
Registrierte Kanäle erhalten Sie übergetChannels() des Treibers als Collection. Die Schlüssel sind die Kanalnamen selbst.
/broadcasting/auth. Die Treiber null und log geben aus auth() nichts zurück und eignen sich daher nicht für diesen Test. Kanäle werden beim Start der Anwendung beim Standardtreiber registriert. Setzen Sie deshalb BROADCAST_CONNECTION zum Beispiel in der phpunit.xml für Tests auf reverb oder pusher, bevor Sie den authentifizierten Request senden.
Hinweise zur Wartung
- Kanalnamen sind ein öffentlicher Vertrag. Wenn Sie einen Namen ändern, können bestehende Clients den Kanal nicht mehr abonnieren.
- Klassenbasierte Kanäle werden über den
Containeraufgelöst. Verwenden Sie für Konstruktorabhängigkeiten Typen, die der Container auflösen kann.
Zusammenfassung
Die Kanal-Autorisierung eines Pakets funktioniert, sobald SieBroadcast::channel() in boot() registrieren. Registriert die routes/channels.php der nutzenden Anwendung später denselben Namen, wird die Autorisierung des Pakets ersetzt. Ein Präfix im Kanalnamen, eine eigene Klasse für die Prüfung und HTTP-Tests für das Ergebnis von /broadcasting/auth machen das Paket leichter wartbar.