2
votes

I am creating a "digital queue ticket" application, where people can host a queue and others, line up. If you line up you will basically see the nr currently being served, nr of people in line, ETA, etc. It's web-based and I decided to use SSE to push changes (for example when nr currently being served changes) to everyone in that specific queue.

I need a way to map/identify each client so that if they disconnect for a while and then reconnect they will still keep their place in line. I am aware that if there is an error, the browser or SSE client will automatically attempt to reconnect. Usually delayed a few seconds depending on the browser. Furthermore, the data stream continues from the point it disconnected, so no messages are lost using Last-Event-Id.

But if, for example, the user quits safari by mistake, reopens it and head back to the same URL, a new connection will be set up, ie it does not "reconnect".

I have considered tokens or cookies to accomplish this. However, SSE standard does not support sending headers (or POST data). Only GET data and cookies. I could pass a token as a query parameter. Here some info I've read on this:

https://community.apigee.com/questions/28794/best-practices-for-passing-an-access-token-without.html

https://www.rfc-editor.org/rfc/rfc6750#section-2.3

People discuss security issues regarding this but I was thinking that since people line up anonymously and the fact that token would only be used to identify reconnecting clients this would not be an issue. Also, I am in charge of both the back end and front end.

Using cookies might also work, but I know pretty much nothing about how they work. I assume I need a persistent cookie to identify a client that is "reconnecting"? If not perhaps I should use WebSockets instead, or polling?. The reason I chose SSE was that I only need unidirectional communication.

I am quite new to this so any tips are appreciated! Been reading everything I can get my hands on for days but haven't found a good solution so far. Perhaps there is some other way to accomplish what I want?

2
Use a cookie to identify a client using SSE, WebSocket or polling. Note that some browsers do not support SSE (compat chart).Cerise Limón

2 Answers

1
votes

I would definitely go with the cookie. I haven't tried this in Go, but this link shows how to set and receive cookies.

Downsides would be that a user can bypass it by deleting cookies (and they may be motivated to do this, so they can jump the queue?), and (in the EU at least) having to show a "we use cookies" notice. You mentioned the case of the user closing their browser, so a session cookie is not enough, you'd need to use a cookie with an expiration time.

A second choice would be to try and "fingerprint" the user, by a combination of user-agent, IP address, and maybe some other headers. That is unreliable though, especially if users are sharing a proxy, VPN, etc. (And someone could still get round it, e.g. switching browser, or using a plugin that allows changing user-agent.)

0
votes

Set id in the SSE message, browser will sent the last event id header when reconnecting. also, its server responsibility to keep track of which message has been delivered or lost in due to client disconnect.

https://www.html5rocks.com/en/tutorials/eventsource/basics/#toc-lastevent-id