I have a Symfony backend (BoltCMS) with a custom CaddyServer with the Mercure plugin and I am trying to send a message to my Angular 16 frontend on the event when I save something in the backend so that I can refresh the cache in the Angular application.
I am able to successfully publish the SSE from Symfony to the Mercure/CaddyServer.
However I am having some trouble subscribing to said event. Because I want to authenticate client side subscriptions I cannot use the built in mechanism in Angular if I understood correctly (using EventSource)?
On my search through the internet I found the ng-sse-client package with which - according to the README - I should be able to pass a authentication token in the header:
...
import { SseClient } from 'ngx-sse-client';
...
constructor(private sseClient: SseClient) {
const headers = new HttpHeaders().set('Authorization', `Basic YWRtaW46YWRtaW4=`);
this.sseClient.stream('/subscribe', { keepAlive: true, reconnectionDelay: 1_000, responseType: 'event' }, { headers }, 'POST').subscribe((event) => {
if (event.type === 'error') {
const errorEvent = event as ErrorEvent;
console.error(errorEvent.error, errorEvent.message);
} else {
const messageEvent = event as MessageEvent;
console.info(`SSE request with type "${messageEvent.type}" and data "${messageEvent.data}"`);
}
});
}
However, when I try to call the mentioned function, I get an error, indicating that the function call only accepts 2 erguments instead of 4: Expected 1-2 arguments, but got 4.
When I ctrl+click on the stream function to navigate to the function definition, located in node_modules/ngx-sse-client/lib/sse-client.service.d.ts
, it indeed shows a function which only accepts 2 arguments:
stream(url: string, options?: {
keepAlive?: boolean;
reconnectionDelay?: number;
responseType?: 'event';
}):
The weird thing is I am able to find a function definition in another location sse-client.service.ts which does in fact have 4 arguments. So it looks like I am importing the wrong function or something?
I have looked online, but saw nobody else having similar issues, so I'm thinking I must be doing something wrong, but I've been unable to figure it out.
Any help would be appreciated, either in pointing me in the right direction for an alternative solution/package, or an indication regarding to what I am doing wrong in using this package.
For me it feels weird that something like this is not natively supported in Angular, but I am rather new to Angular, and its quite difficult to find consistent information online, since there are so many different versions with their respective changes.
I have also read about WebSockets, but from what I understood this would be quite overkill for my use-case. But since I have no experience with either SSE or WebSockets, I might be mistaken, and this might be a viable approach?
What I've tried:
I tried calling the SseClient.stream() function with 4 arguments, expecting it to work, but I got an error that it only accepts 2 arguments.
While I still haven't found a way to get the ng-sse-client to work, after some more digging I have found several solutions to accomplish the sending of an authorization token to Mercure from Angular:
mercureAuthorization
), marked with Secure
, HtttpOnly
and SameSite
(this is the recommended method)devDependencies
, using npm i --save-dev @types/event-source-polyfill