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?
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With