hapi-plugin-websocket
hapi-plugin-websocket copied to clipboard
Incompatible Auth Heuristics
hapi is an HTTP server implementation. hapi-plugin-websocket tries to implement WebSocket support over this implementation. In regarding to auth, the current heuristics doesn't follow WebSocket practices.
A native WebSocket server handles auth in the following way:
- Receive an HTTP request to upgrade connection to WS. In this request, the server checks auth requirements.
- If the request passes auth requirements, the server opens a WS connection.
- If the request doesn't pass auth requirements, the server sends an HTTP error response (401, 403, etc.).
- No need for any more auth checking on the opened WS connection (except for the handshake keys when opening the connection which the server does automatically).
In hapi-plugin-websocket, the following heuristics for auth is provided:
- An HTTP request to upgrade to WS connection is always accepted (unless 404). I.e., a WS connection is always opened, and
options.plugins.websocket.connectis always called. - Each time a data packet over the WS connection is received, prior to calling the
handler, auth is checked. The auth is basically checked against the original HTTP upgrade request over and over again. Since the input is the same, each check results in the same conclusion (and hence redundant).
Not only that this heuristics don't follow the conventional WebSocket way, but it does introduce problems, such as:
- Client are not notified in the standard WS/HTTP way of auth problems via 401, 403 responses.
- Handling out of order of packets. Let's say that over an WS connection P1, P2, P3 are sent. If P2 is handled a bit slower by an async auth method than the handling of P1 and P3, the
handlermy get the packets in the order of P1, P3 and P2.
In order to solve these issues
- Auth should be called only once.
- Move the auth and
options.plugins.websocket.connecttonew WS.Server({verifyClient})method. - Add
htooptions.plugins.websocket.connectmethod to return errors (not related to auth) in the standard WS/HTTP way.