I've been blocking this issue for 2 days now. I'm trying to set up authentication for Mercure so that a customer can subscribe to "private" hubs. So I configured my environment variables as stipulated in the Symfony and Mercury documentation here they are:
my .env of my app Symfony:
###> mercure/bundle ###
MERCURE_URL=http://mydemoapp.com:80/.well-known/mercure
MERCURE_PUBLIC_URL=http://mydemoapp.com:80/.well-known/mercure
MERCURE_JWT_SECRET=MySecretKeyJWT
MERCURE_JWT_TOKEN=MyTokenJWT
###< mercure/bundle ###
my caddyFile :
{
# Debug mode (disable it in production!)
debug
# HTTP/3 support
experimental_http3
}
:80
log
route {
redir / /.well-known/mercure/ui/
encode gzip
mercure {
# Enable the demo endpoint (disable it in production!)
demo
# Publisher JWT key
publisher_jwt MySecretKeyJWT
# Subscriber JWT key
subscriber_jwt MySecretKeyJWT
# CORS
cors_origins http://127.0.0.1:3005
# Allow anonymous subscribers (double-check that it's what you want)
anonymous
# Enable the subscription API (double-check that it's what you want)
subscriptions
}
respond "Not Found" 404
}
my container Mercure :
mercure:
image: dunglas/mercure
container_name: mercure
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- mercure:/data
labels:
- traefik.docker.network=proxy
- traefik.enable=true
- traefik.http.routers.mercure.rule=Host(`mydemoapp.com`)
expose:
- "80"
networks:
- app
And here is the code of my controllers to generate the authorization cookie and the route publishing the hub:
my routes authorization:
/**
* @Route("/api/v1.0/ms-security/authorization", name="security.index", methods={"GET"})
*/
public function index(Authorization $authorization, Request $request): Response
{
$response = $this->json([
'message' => 'Your authorization has been generated !',
'code' => '200',
]);
$response->headers->setCookie($authorization->createCookie($request, ["http://mydemoapp.com:80/api/v1.0/ms-security/23"]));
return $response;
}
my routes for publish on hub ( This routes is only a test route to know if my client is well subscribed and receives the notifications ):
/**
* @Route("/api/v1.0/ms-match/invitations/test", name="invitation.test", methods={"GET"})
*/
public function test(HubInterface $hub)
{
$update = new Update("{$this->getParameter('base.url')}/ms-security/23", json_encode("Hy it's me {$this->getUser()->getId()} !"), true);
$hub->publish($update);
return $this->json(["message" => "ok"]);
}
and my javascript :
async mounted(){
let data = {"phone": "myPhone", "password": "myPassword"};
const resAuth = await fetch("http://mydemoapp.com:80/api/v1.0/ms-security/login", {method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data)});
const dataAuth = await resAuth.json();
console.log(dataAuth);
const res = await fetch("http://mydemoapp.com:80/api/v1.0/ms-security/authorization", {method: "GET", headers: {'Authorization': `Bearer ${await dataAuth.token}`}});
const dataCookie = await res.json();
console.log(dataCookie)
const url = new URL('http://mydemoapp.com:80/.well-known/mercure');
url.searchParams.append('topic', 'http://mydemoapp.com:80/api/v1.0/ms-security/23');
const eventSource = new EventSource(url, {withCredentials: true});
console.log(eventSource.withCredentials)
eventSource.onmessage = e => console.log(e.data);
}
When I call my route "authorization" I see in my response header that I really have the cookie to send. When I decode it on JWT.IO we can see that my jwt contains the information to subscribe to this hub, however when I call my test route the client does not receive the notification if I send this hub in private (in public everything goes very well). So I have the impression that cookies do not send.