Websockets客户端API中的HTTP标头

2020/10/15 05:41 · javascript ·  · 0评论

看起来很容易使用支持此功能的任何HTTP标头客户端向您的websocket客户端添加自定义HTTP标头,但是我找不到如何使用JSON API进行操作。

但是,似乎应该在规范中支持这些标头

任何人都知道如何实现这一目标?

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

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

更新了2倍

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

更长的答案:

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

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

Sec-WebSocket-Protocol: protocol1, protocol2

实现WebSocket身份验证/授权的一种常见模式是实现一种票证系统,其中托管WebSocket客户端的页面从服务器请求票证,然后在WebSocket连接设置过程中的URL /查询字符串中,在协议字段中传递该票证,或要求在建立连接后作为第一条消息。然后,服务器仅在票证有效时(存在,尚未使用,票证匹配中编码的客户端IP,票证中的时间戳是最近的等)允许连接继续。以下是WebSocket安全信息的摘要:https : //devcenter.heroku.com/articles/websocket-security

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

基本身份验证信息(不建议使用)

Authorization标头是从WebSocket URI的用户名和密码(或仅用户名)字段生成的:

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

上面的结果导致以下标头带有字符串“ username:password” base64编码:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

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

感谢Dmitry Frank的基本身份验证答案

更多的替代解决方案,但是所有现代浏览器都将域cookie和连接一起发送,因此请使用:

var authToken = 'R3YKZFKBVi';

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

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

以请求连接头结尾:

Cookie: X-Authorization=R3YKZFKBVi

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

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

然后,将使用提供的username设置适当的基本授权HTTP标头password如果您需要基本授权,那么一切都准备就绪。


Bearer但是,我想使用,并且采取了以下技巧:我按如下所示连接到服务器:

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

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

您不能添加标头,但是,如果只需要在连接时将值传递给服务器,则可以在url上指定查询字符串部分:

var ws = new WebSocket("ws://example.com/service?key1=value1&key2=value2");

该URL是有效的,但是-当然-您需要修改服务器代码才能对其进行解析。

要使用JavaScript WebSockets API建立WebSockets连接时,无法发送自定义标头。您可以Subprotocols通过使用第二个WebSocket类构造函数来使用标头:

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

然后您可以使用Sec-WebSocket-Protocol服务器上的密钥获取Subprotocols标头

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

无法发送授权标头。

附加令牌查询参数是一种选择。但是,在某些情况下,可能不希望以纯文本形式将主登录令牌作为查询参数发送,因为它比使用标头更不透明,并且最终会被记录在任何地方。如果这给您带来了安全隐患,则替代方法是仅将辅助JWT令牌用于Web套接字

创建用于生成此JWT的REST端点,当然,只有使用您的主要登录令牌(通过标头传输)进行身份验证的用户才能访问该端点Web套接字JWT的配置可以与登录令牌不同,例如,超时时间更短,因此,将其作为升级请求的查询参数进行发送时更加安全。

为您在上注册SockJS eventbusHandler的同一路由创建一个单独的JwtAuthHandler确保首先注册了身份验证处理程序,以便您可以针对数据库检查Web套接字令牌(JWT应该以某种方式链接到后端的用户)。

多亏kanaka的回答,才完全这样破解了它。

客户:

var ws = new WebSocket(
    'ws://localhost:8080/connect/' + this.state.room.id, 
    store('token') || cookie('token') 
);

服务器(在此示例中使用Koa2,但无论如何都应相似):

var url = ctx.websocket.upgradeReq.url; // can use to get url/query params
var authToken = ctx.websocket.upgradeReq.headers['sec-websocket-protocol'];
// Can then decode the auth token and do any session/user stuff...

我的情况:

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

document.cookie = "sessionid=foobar;path=/"由于域名不匹配,设置无济于事。

解决方案

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

这样,mycompany.comwww.mycompany.com/api/ws您从有效子域进行连接时,浏览器将在连接时使用cookie wsdev.company.com

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

从技术上讲,您将在协议升级阶段之前通过connect函数发送这些标头。这在一个nodejs项目中为我工作:

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

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


ws = new WebSocket('ws:// localhost',null,{标头:{授权:令牌}})

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

本文地址:http://javascript.askforanswer.com/websocketskehuduanapizhongdehttpbiaotou.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!