| Hi, Mercure author here. WebSockets are hard to secure (they totally bypass CORS as well as other browser built-in protections), don't work (yet) with HTTP/3 and for most use cases require to implement many features by yourself: reconnection in case of network failure, refetch of lost messages, authorization, topic mechanism… Mercure, which is built on top of SSE (it's more an extension to SSE than an alternative to it) fix these issues. However, SSE (as well as WebSockets) can be hard to use with stacks not designed to handle persistent connections such as PHP, serverless, most web servers proxying Ruby, Python etc apps. Even for languages designed to handle persistent connections, it's often more efficient and easier to manage persistent connections with ah-hoc software running on dedicated hardware. That's what Mercure allows. Mercure provides a "hub", a server that will maintain the persistent connections with the browsers, store events, and re-send them in case of network issues (or if asked for old messages by a client). To broadcast a message to all connected users, the server app (or even a client) can just send a single POST request to the hub. The hub will also check that clients are authorized to subscribe or publish to a given topic (that's why JWT is used). The reference implementation is written in Go, as a module for the Caddy web server, and his very efficient/optimized (it can handle thousands of persistent connections on very small machines). Install a Mercure hub and you have all these features available without having to write any code. Client-side, no SDK is required, you can embrace the built-in EventSource JavaScript class. |
You can reimplement the Same Origin Policy serverside by checking that the Origin header equals the Host header. Even more secure would be to check both against an allowlist (this protects against DNS rebinding, which the Same Origin Policy doesn't protect against).
>as well as other browser built-in protections
I'm curious what those are.
>for most use cases require to implement many features by yourself: [...] authorization
Isn't auth of websockets generally the same as auth of any Javascript-initiated HTTP request (e.g. fetch())? Check that the cookie looks good? Now, in the cause of OAuth tokens, websockets are more difficult than fetch(), because you cannot attach an Authorization: Bearer header to a websocket. But OAuth is less common than cookies for websites.