Créez un chat avec Mercure et Symfony

Créez un chat avec Mercure et Symfony


Mercure va nous permettre d'envoyer et recevoir en temps réel nos messages, sans avoir à reloader les navigateurs déjà connectés au chat.

Dans un premier temps, il nous faut le package composer qui nous permettra d'interagir avec notre Hub Mercure.

Installation

Vous avez sans doute remarqué des warnings dans votre console à propos de variables d'environnement Mercure.

Il est temps de s'en occuper en installant le package mercure depuis composer.

docker-compose exec php composer req mercure

De nouvelles variables d'environnement sont apparues dans votre .env. Allez les modifier pour obtenir ce résultat :

MERCURE_PUBLISH_URL=http://mercure/.well-known/mercure MERCURE_JWT_KEY=astronautsKey MERCURE_ALLOW_ANONYMOUS=1 MERCURE_CORS_ALLOWED_ORIGINS=* MERCURE_PUBLISH_ALLOWED_ORIGINS='http://localhost'

En production, ne laissez jamais ces données sensibles en clair dans ce fichier.

Petit rappel tout de même. Avec Mercure, vous décidez d'updates qui seront publiées vers un Hub, avec pour identifiant un topic. À son tour, le Hub dispatche ces updates à tous les clients abonnés au topic en question.

Plusieurs points ici :

  • Le PUBLISH_URL est l'adresse du Hub mercure sur lequel on veut publier nos updates
  • Le MERCURE_JWT_KEY est la clé secrète qui nous permettra de générer un token JWT
  • Et avec PUBLISH_ALLOWED_ORIGINS, on autorise Mercure à accepter les Publishers depuis le domaine localhost

Ici donc, admettons que les topics soient nos différents channels. Ces derniers lanceront des updates au Hub à chaque nouveau message envoyé, en étant identifiés par un topic que nous définirons plus loin.

Autoriser notre application à publier sur le Hub

Si vous vous rappelez bien de l'article de découverte de Mercure, vous savez qu'il est nécessaire de générer un JWT Token afin de pouvoir publier sur le Hub.

Afin de le générer depuis la clé secrète précisée dans le .env, nous allons utiliser le package lcobucci/jwt.

docker-compose exec php composer req lcobucci/jwt

Créons à présent un service invokable pour générer automatiquement notre token JWT :

<?php declare(strict_types=1); namespace App\Service\Mercure; use Lcobucci\JWT\Builder; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key; class JwtProvider { private string $key; public function __construct(string $key) { $this->key = $key; } public function __invoke(): string { $signer = new Sha256(); return (new Builder()) ->withClaim('mercure', ['publish' => ['*']]) ->getToken($signer, new Key($this->key)) ->__toString(); } }

Remarquez que le Claim de notre builder représente le json que nous avions utilisé sur jwt.io dans l'article de blog.

Il se passe ici exactement la même chose, mais dynamiquement avec PHP. En récupérant le token, on le signe avec une signature de type SHA256.

Faites attention à rentrer correctement le claim, avec la bonne clé et la bonne valeur, autrement Mecure vous refusera l'accès au Hub avec une 401 Unauthorized.

Pour injecter automatiquement la clé que ce service attend dans son constructeur, ajoutez ces lignes dans services.yaml :

services: # ... App\Services\Mercure\JwtProvider: arguments: $key: '%env(MERCURE_JWT_KEY)%'

Enfin, rendez-vous dans le fichier de config mercure.yaml qui vous a été généré, et remplacez la config par celle-ci :

mercure: enable_profiler: '%kernel.debug%' hubs: default: url: '%env(MERCURE_PUBLISH_URL)%' jwt_provider: App\Services\Mercure\JwtProvider

Notre service est à présent fonctionnel.

Ainsi c'est notre nouveau service qui sera invoqué pour générer un nouveau JWT et nous autoriser à publier sur le Hub.

D'ailleurs, relancez toute l'application (docker-compose down && docker-compose up -d) afin que les nouvelles variables d'environnement soient bien prises en compte.

Vous pouvez vous rendre sur cette branche pour être à jour sur cette étape du tutoriel, et continuer sereinement vers la prochaine partie.

Auteur(s)

Arthur Jacquemin

Arthur Jacquemin

Développeur de contenu + ou - pertinent @ ElevenLabs_🚀

Voir le profil

Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !

Notre équipe d'experts répond à toutes vos questions.

Nous contacter

Découvrez nos autres contenus dans le même thème