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

有人知道怎么做到吗?

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

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


当前回答

您可以在对象的第三个参数(选项)中将头作为键值传递。 使用授权令牌的示例。将协议(第二个参数)保留为空


ws = new WebSocket(‘ws://localhost’, null, { headers: { Authorization: token }})

编辑:这种方法似乎只适用于nodejs库,不适用于标准的浏览器实现。因为它可能对某些人有用。

其他回答

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

var authToken = 'R3YKZFKBVi';

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

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

以请求连接头结束:

Cookie: X-Authorization=R3YKZFKBVi

推荐的方法是通过URL查询参数

// authorization: Basic abc123
// content-type: application/json
let ws = new WebSocket(
  "ws://example.com/service?authorization=basic%20abc123&content-type=application%2Fjson"
);

这被认为是一个安全的最佳实践,因为:

WebSockets不支持头文件 在HTTP -> WebSocket升级期间,建议不要使用报头,因为CORS不是强制的 SSL加密查询参数 浏览器不会像缓存url那样缓存WebSocket连接

更新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中不起作用)。

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

HTTP授权头问题可以通过以下方式解决:

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

然后,将使用提供的用户名和密码设置一个正确的基本授权HTTP报头。如果您需要基本授权,那么您就万事俱备了。


我想使用承载,但是,我采取了以下技巧:我连接到服务器如下:

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

当我的代码在服务器端接收到基本授权头非空用户名和空密码时,它将用户名解释为令牌。

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

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

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

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