4 ms·
What is the right way to handle authentication over web sockets?
by friendlydog 5y ago
What is the right way to handle authentication over web sockets?
- z3t4 5y agoIf I understand correctly, websockets is a thin layer on TCP that does buffer data so that the application get the whole message instead of chunks. I recommend using wss to secure the websocket so that it can't be hijacked, then you don't need to send a token in each message and can do an application layer handshake once. Basically the first websock message from the client would be an authentication message with a password, token or what not.
- syspec 5y agoYeah this is the technique I've also used. The first websocket message is the original request, which will have the users cookies / headers where your session information / bearer token should live.
- AlexTDiaconu 5y agoAs with REST APIs, you'd want to be able to authenticate to a websocket-based API using either basic auth, or a bearer token-based auth scheme. Unfortunately, the browser websocket API doesn't allow you to specify arbitrary headers in the websocket request, so it's typical instead to have credentials supplied via a query param (such as "accessToken" for a bearer token) in the wss request.
- capableweb 5y ago> so it's typical instead to have credentials supplied via a query param (such as "accessToken" for a bearer token) in the wss request. If someone ends up actually doing this in a production system, remember to not to log the accessToken if you're logging full paths/URIs somewhere, as query params usually is a part of that type of logging.
- matt_oriordan 5y agoYup, true, although tokens should be ephemeral so less of a risk. Authenticating inline over the Websocket connection is valid too, but it does expose the socket connections to slightly more surface area of attack i.e. if you pass in a token as a param, the Websocket request can be rejected immediately. If however you authenticate after establishing a Websocket connection, then there is an attack vector where you simply open Websocket connections and never authenticate. Of course timeouts can be used to disconnect rogue actors, but it is a consideration. Matt, Ably co-founder
- JSdev1 5y agoIt's the same thing as HTTP. Websocket starts off as an HTTP request with cookies, headers etc. Use those just like HTTP to authenticate, and your Websocket server should pass the user data to the websocket object
- latch 5y agoDon't have access to the headers from JS. Best solution might be to generate a short-lived one-time-use ticket and pass it in the querystring.
- simonkagedal 5y agoCookies will be forwarded though, or..?
- twic 5y agoIf you make a normal HTTP request first, the server can issue a standard HTTP cookie to the client. That cookie will then be included when the browser makes the websocket request. However, websockets are not subject to the same-origin policy, so this exposes you to CSRF [1]. To protect against that, you should check the Origin header on the server side. [1] https://christian-schneider.net/CrossSiteWebSocketHijacking.html https://christian-schneider.net/CrossSiteWebSocketHijacking....
- dimgl 5y agoIn a Golang app I'm writing now, I have middleware that authorizes requests. Authenticated requests have a header with a JWT token. I have an endpoint for websockets where if an authenticated request comes in (the handshake) that request is then upgraded to a Websocket connection. This is the cleanest authentication implementation I've ever used thus far, and I wasn't able to achieve the same thing in Node when I was using socket.io. I'm sure there are repercussions to this on the client-side, but I haven't gotten to that point yet. I'm still writing the server and testing it using automated integration tests.