6

Context:

I'm developing a frontend app locally, calling APIs etc cross-domain (from localhost dev server to our server on another machine inside the local network). Since our local network is isolated, the backend server has CORS enabled which doesn't cause security problems; this is different in production (CORS is disabled).

We introduced WebSocket connections in our app and to secure it with authorization we added cookie check on handshake. (XHR requests are authorized via the Authorization header, cookies are not used there; but they actually can be used; WebSocket interface only allows a limited set of headers and if we don't authorize via WS messages, cookies seem to be the only sane option; well, in fact I failed to find if Basic HTTP auth can be implemented without broswer standart prompt, and how to do that)

The problem:

while this actually works for production (when frontend and backend are on the same domain), and cookies are sent in the handshake request inside the Cookie header (the code is trivial: I just set the cookie after getting the auth token), this doesn't work in development environment (localhost + backend on another domain): the Cookie header is just absent in the handshake. The link above shows that XHR needs the withCredentials option to try to pass cookie cross-domain; however, I haven't found a definitive answer whether there's something similar for WS or not. Here the author of a similar question just assumes that there's no such thing, but is it really so?

YakovL
  • 7,557
  • 12
  • 62
  • 102
  • I don't have any insight to offer, but I suffer from the same issue. I've spent the entire day searching, and I can't seem to find any work around to allow you to pass a cookie for CORS websocket requests. It seems we have to rely on the browser to pass the cookie as it normally would for websockets, but the browser doesn't do that unless you specifically tell it to (typically with the withCredentials option as you noted) – SharpLizard Jan 09 '20 at 16:55
  • @SharpLizard well, we ended up with deactivating auth for WS in dev environment; I'd say that it would be more consistent to implement auth using WS messages themselves instead of cookies – YakovL Jan 09 '20 at 18:07

2 Answers2

2

Double check that the cookies that you're working with are set with SameSite=None and are secure!

I was having the same issue, thinking that the cookies weren't being sent, because the chrome inspector doesn't show them on websocket connection request, but they seem to be once you mark them with same site none and secure.

Alternatively, to quickly check if that's the problem, you can disable the SameSite requirement in chrome://flags/

Martin Tomov
  • 31
  • 1
  • 5
  • right, thanks, I'm "far away" from the code where I needed that, so can't really check at once if this works for me and accept, but I upvoted indicating this may be helpful and deserves trying – YakovL Jun 21 '20 at 09:00
-1

On another project I've learned a "correct" way to handle this. Usually a higher level protocols are used with WS, like STOMP protocol. It has specific implementation for auth, so no cookies are needed actually; it has no drawbacks regarding CORS.

YakovL
  • 7,557
  • 12
  • 62
  • 102