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

有人知道怎么做到吗?

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

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


当前回答

更新2 x

简单回答:不能,只能指定路径和协议字段。

再答:

在JavaScript WebSockets API中没有方法指定额外的头信息给客户端/浏览器发送。HTTP路径(“GET /xyz”)和协议头(“Sec-WebSocket-Protocol”)可以在WebSocket构造函数中指定。

Sec-WebSocket-Protocol报头(有时会扩展到websocket特定的认证中使用)由websocket构造函数的可选第二个参数生成:

var ws = new WebSocket("ws://example.com/path", "protocol");
var ws = new WebSocket("ws://example.com/path", ["protocol1", "protocol2"]);

上面的结果是下面的头文件:

Sec-WebSocket-Protocol: protocol

and

Sec-WebSocket-Protocol: protocol1, protocol2

A common pattern for achieving WebSocket authentication/authorization is to implement a ticketing system where the page hosting the WebSocket client requests a ticket from the server and then passes this ticket during WebSocket connection setup either in the URL/query string, in the protocol field, or required as the first message after the connection is established. The server then only allows the connection to continue if the ticket is valid (exists, has not been already used, client IP encoded in ticket matches, timestamp in ticket is recent, etc). Here is a summary of WebSocket security information: https://devcenter.heroku.com/articles/websocket-security

基本身份验证以前是一个选项,但这已经被弃用,现代浏览器即使指定了头信息也不会发送。

基本认证信息(已弃用-不再功能):

注意:以下信息在任何现代浏览器中都不再准确。

授权头是由WebSocket URI的用户名和密码(或者只是用户名)字段生成的:

var ws = new WebSocket("ws://username:password@example.com")

上面的结果是在下面的头文件中使用base64编码的字符串"username:password":

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

我已经在Chrome 55和Firefox 50中测试了基本身份验证,并验证了基本身份验证信息确实是与服务器协商的(这可能在Safari中不起作用)。

感谢德米特里·弗兰克给出的基本验证答案

其他回答

在我的情况下(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

我的情况:

我想连接到一个生产WS服务器www.mycompany.com/api/ws… 使用真实凭证(会话cookie)… 从本地页面(localhost:8000)。

设置文档。Cookie = "sessionid=foobar;path=/"不会有帮助,因为域不匹配。

解决方案:

将127.0.0.1 wsdev.company.com添加到/etc/hosts.

这样,当您从有效的子域wsdev.company.com连接到www.mycompany.com/api/ws时,浏览器将使用来自mycompany.com的cookie。

更新2 x

简单回答:不能,只能指定路径和协议字段。

再答:

在JavaScript WebSockets API中没有方法指定额外的头信息给客户端/浏览器发送。HTTP路径(“GET /xyz”)和协议头(“Sec-WebSocket-Protocol”)可以在WebSocket构造函数中指定。

Sec-WebSocket-Protocol报头(有时会扩展到websocket特定的认证中使用)由websocket构造函数的可选第二个参数生成:

var ws = new WebSocket("ws://example.com/path", "protocol");
var ws = new WebSocket("ws://example.com/path", ["protocol1", "protocol2"]);

上面的结果是下面的头文件:

Sec-WebSocket-Protocol: protocol

and

Sec-WebSocket-Protocol: protocol1, protocol2

A common pattern for achieving WebSocket authentication/authorization is to implement a ticketing system where the page hosting the WebSocket client requests a ticket from the server and then passes this ticket during WebSocket connection setup either in the URL/query string, in the protocol field, or required as the first message after the connection is established. The server then only allows the connection to continue if the ticket is valid (exists, has not been already used, client IP encoded in ticket matches, timestamp in ticket is recent, etc). Here is a summary of WebSocket security information: https://devcenter.heroku.com/articles/websocket-security

基本身份验证以前是一个选项,但这已经被弃用,现代浏览器即使指定了头信息也不会发送。

基本认证信息(已弃用-不再功能):

注意:以下信息在任何现代浏览器中都不再准确。

授权头是由WebSocket URI的用户名和密码(或者只是用户名)字段生成的:

var ws = new WebSocket("ws://username:password@example.com")

上面的结果是在下面的头文件中使用base64编码的字符串"username:password":

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

我已经在Chrome 55和Firefox 50中测试了基本身份验证,并验证了基本身份验证信息确实是与服务器协商的(这可能在Safari中不起作用)。

感谢德米特里·弗兰克给出的基本验证答案

不可能发送授权头。

附加令牌查询参数是一个选项。然而,在某些情况下,以纯文本作为查询参数发送主登录令牌可能是不可取的,因为它比使用报头更不透明,并且最终会被记录在任何地方。如果这引起了您的安全问题,另一种替代方法是仅为web套接字使用第二个JWT令牌。

创建一个REST端点来生成这个JWT,当然,只有使用主登录令牌(通过报头传输)进行身份验证的用户才能访问它。web套接字JWT可以配置不同于您的登录令牌,例如有一个更短的超时,所以它是更安全的发送作为您的升级请求的查询参数。

为注册SockJS eventbusHandler的同一路由创建一个单独的JwtAuthHandler。确保先注册了认证处理程序,这样你就可以根据数据库检查web套接字令牌(JWT应该在后端以某种方式链接到你的用户)。