Passer au contenu principal
Lorsqu’un package diffuse des événements en temps réel, concevez séparément la définition du nom du canal et la vérification de qui peut le rejoindre. Un canal que le package enregistre dans boot() peut être surchargé si le routes/channels.php de l’application utilise le même nom. Comprendre cet ordre d’enregistrement et d’évaluation permet de réduire les bugs lors de la maintenance. Cette page s’appuie sur la documentation officielle de Laravel sur le broadcasting et sur l’implémentation de la dernière version v13.42.0, utilisée pour la vérification. Pour l’envoi des événements, consultez broadcasting. Pour le chargement des providers, consultez découverte automatique des packages.

Fonctionnement de l’autorisation des canaux

Lorsqu’un client s’abonne à un canal privé, il envoie une requête à /broadcasting/auth. BroadcastController::authenticate() transmet le traitement à Broadcast::auth(), et le Broadcaster évalue les callbacks enregistrés dans l’ordre. Les règles d’évaluation sont les suivantes :
  • Si un callback retourne false, une AccessDeniedHttpException est levée immédiatement.
  • S’il retourne une valeur vraie comme true, l’autorisation est accordée à ce moment-là.
  • S’il retourne une valeur fausse comme null, l’évaluation passe au callback enregistré suivant. Si aucun n’accorde l’accès, une AccessDeniedHttpException est levée à la fin.
Les drivers Pusher et Reverb retirent les préfixes private- et presence- avant l’autorisation. N’incluez donc pas le préfixe dans les noms de canaux que vous enregistrez.

Enregistrer un canal dans le package

Prenons l’exemple d’un package fictif Acme\Orders qui diffuse les changements d’état des commandes. Le nom du canal est acme.orders.{order}, et seul le propriétaire de la commande peut s’y abonner. Dans le ServiceProvider du package, appelez Broadcast::channel() dans boot(). Déléguez la vérification à une classe du package.
Le premier argument de join() reçoit l’utilisateur au moment de l’autorisation. Les arguments suivants reçoivent les valeurs des {...} du nom du canal. Si le nom du paramètre {order} correspond à Order $order et que le type est une sous-classe de UrlRoutable, le route model binding s’applique.
Le $callback de Broadcast::channel() peut être un callable ou le nom d’une classe possédant une méthode join(). Pour un nom de classe, Broadcaster::normalizeChannelHandlerToCallable() crée l’instance via le conteneur, puis appelle join().

Surcharge par l’application

Le fichier que l’application passe à withBroadcasting() (en général routes/channels.php) est chargé dans un callback booted que withBroadcasting() enregistre. Les callbacks booted s’exécutent une fois le boot() de tous les service providers terminé : l’enregistrement fait dans le boot() du package a donc lieu en premier. Broadcaster::channel() stocke les callbacks dans un tableau interne dont la clé est le nom du canal. Si l’application enregistre le même nom, le second enregistrement remplace donc celui du package. Laravel ne signale pas un nom en double comme une erreur. Pour éviter la surcharge, rendez le nom du canal unique. Par exemple, avec un préfixe propre au package comme dans acme.orders.{order}, il devient moins probable que l’application enregistre le même nom. Le nom du canal est un contrat public avec les clients. Une fois choisi, ne le modifiez pas. Si vous le modifiez, les anciens clients ne pourront plus s’abonner.
Entre deux canaux du même nom, celui enregistré en dernier l’emporte sans avertissement. php artisan channel:list affiche le nom du canal et sa cible de résolution (nom de classe ou Closure), ce qui permet de vérifier quel enregistrement est en vigueur.

Options du canal et guards

Le troisième argument $options de Broadcast::channel() est enregistré comme configuration propre au canal. Si vous indiquez guards, les guards utilisés pour l’authentification sont essayés dans l’ordre.
Si guards est omis, l’utilisateur par défaut de la requête ($request->user()) est utilisé pour l’autorisation. Si guards est indiqué, $request->user($guard) est appelé dans l’ordre depuis le début, et le premier utilisateur obtenu est utilisé. Si le package ne fige pas les noms de guards et les expose comme valeur de configuration, l’application peut les choisir.

Vérifier l’enregistrement des canaux dans les tests

Les canaux enregistrés s’obtiennent sous forme de Collection avec la méthode getChannels() du driver. Les clés sont les noms de canaux eux-mêmes.
Vérifiez le résultat de l’autorisation avec un test HTTP sur /broadcasting/auth. Les drivers null et log ne retournent rien depuis auth() et ne conviennent donc pas à ce test. Les canaux sont enregistrés sur le driver par défaut au démarrage de l’application : définissez donc BROADCAST_CONNECTION sur reverb ou pusher, par exemple dans le phpunit.xml de test, avant d’envoyer la requête authentifiée.
La route /broadcasting/auth doit être enregistrée dans l’application de test. C’est Broadcast::routes() qui l’enregistre, et BroadcastManager::channelRoutes() se contente de déléguer le même traitement à routes(). Si les routes sont en cache, routes() ne fait rien.

Points d’attention pour la maintenance

  • Le nom du canal est un contrat public. Si vous le renommez, les clients existants ne pourront plus s’abonner.
  • Les canaux basés sur une classe sont résolus par le Container. Utilisez pour les dépendances du constructeur des types que le conteneur sait résoudre.

Résumé

L’autorisation des canaux d’un package fonctionne dès que Broadcast::channel() est enregistré dans boot(). Si le routes/channels.php de l’application enregistre ensuite le même nom, l’autorisation du package est remplacée. Préfixer le nom du canal, isoler la vérification dans une classe et contrôler le résultat de /broadcasting/auth avec des tests HTTP rend le package plus facile à maintenir.

Sources primaires consultées

Dernière modification le 14 novembre 2026