A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

Headers support for WebSocket upgrade request


I’ve just started using WebSockets, and noticed I can’t pass JWT token in the same way as I do with HTTP – through Authorization: Bearer _TOKEN_, since browsers do not seem to support custom headers for WebSocket upgrade. I can’t find any limitation in RFC 6455, so it’s seems to be a browser-only issue.

I believe browsers should support custom headers in WebSocket upgrade requests (with same rules as XHR/Fetch), if just for consistency between different technologies.


Same problem with EventSource.


@ashmind check out the “Opening Handshake” section: https://tools.ietf.org/html/rfc6455#section-4

There are headers that MUST be in there, and there are headers that MAY be in there, but there’s no mention that any arbitrary header has to be supported.

If you need to pass tokens, I would suggest putting them in query string arguments. This is private enough if you are using WebSockets over TLS, although the server itself might log whole URLs. If you control the server part yourself, ensure that it does not log any tokens when it writes to its access log.


@jokeyrhyme I don’t think that is a correct interpretation, see in the same section

   12.  The request MAY include any other header fields, for example,
        cookies [RFC6265] and/or authentication-related header fields
        such as the |Authorization| header field [RFC2616], which are
        processed according to documents that define them.

This explicitly mentions Authorization I want to use here, but allows for other fields as well.


Having looked at the API I think this would be trivial and non-breaking to add and would enable the (now common) use of bearer tokens in the WebSocket handshake as a means of authenticating the connection.

One could allow any custom headers or keep it simple and only allow a value for the Authorization header:

[Constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols = [], optional DOMString authorizationHeader), Exposed=(Window,Worker)]
interface WebSocket : EventTarget {

The algorithm to establish a websocket already has steps to add headers to the handshake so simply including another (if provided in the constructor) seems pretty straight-forward.