看起来很容易添加自定义HTTP头到你的websocket客户端与任何HTTP头客户端支持这一点,但我不知道如何与web平台的websocket API。

有人知道怎么做到吗?

var ws = new WebSocket("ws://example.com/service");

具体来说,我需要能够发送HTTP授权标头。


当前回答

在我的情况下(Azure时间序列洞察wss://)

使用ReconnectingWebsocket包装器,并能够实现添加头与一个简单的解决方案:

socket.onopen = function(e) {
    socket.send(payload);
};

本例中的有效载荷为:

{
  "headers": {
    "Authorization": "Bearer TOKEN",
    "x-ms-client-request-id": "CLIENT_ID"
}, 
"content": {
  "searchSpan": {
    "from": "UTCDATETIME",
    "to": "UTCDATETIME"
  },
"top": {
  "sort": [
    {
      "input": {"builtInProperty": "$ts"},
      "order": "Asc"
    }], 
"count": 1000
}}}

其他回答

我发现最好的方法是将jwt像常规消息一样发送到服务器。让服务器监听此消息并在此时进行验证。如果有效,则将其添加到存储的连接列表中。否则,返回一条消息,说该连接无效并关闭连接。下面是客户端代码。后台是一个使用Websockets的nestjs服务器。

  socket.send(
      JSON.stringify({
        event: 'auth',
        data: jwt
      })
    );

当你想使用JavaScript WebSockets API建立WebSockets连接时,你不能发送自定义头。 你可以通过使用第二个WebSocket类构造函数来使用Subprotocols头:

var ws = new WebSocket("ws://example.com/service", "soap");

然后你可以在服务器上使用Sec-WebSocket-Protocol密钥获取Subprotocols头。

还有一个限制,你的Subprotocols头值不能包含逗号(,)!

在我的情况下(Azure时间序列洞察wss://)

使用ReconnectingWebsocket包装器,并能够实现添加头与一个简单的解决方案:

socket.onopen = function(e) {
    socket.send(payload);
};

本例中的有效载荷为:

{
  "headers": {
    "Authorization": "Bearer TOKEN",
    "x-ms-client-request-id": "CLIENT_ID"
}, 
"content": {
  "searchSpan": {
    "from": "UTCDATETIME",
    "to": "UTCDATETIME"
  },
"top": {
  "sort": [
    {
      "input": {"builtInProperty": "$ts"},
      "order": "Asc"
    }], 
"count": 1000
}}}

更多的替代解决方案,但所有现代浏览器发送域cookie随着连接,所以使用:

var authToken = 'R3YKZFKBVi';

document.cookie = 'X-Authorization=' + authToken + '; path=/';

var ws = new WebSocket(
    'wss://localhost:9000/wss/'
);

以请求连接头结束:

Cookie: X-Authorization=R3YKZFKBVi

从技术上讲,您将在协议升级阶段之前通过connect函数发送这些头文件。这在我的一个nodejs项目中是有效的:

var WebSocketClient = require('websocket').client;
var ws = new WebSocketClient();
ws.connect(url, '', headers);