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

有人知道怎么做到吗?

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

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


当前回答

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

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

其他回答

我的情况:

我想连接到一个生产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。

推荐的方法是通过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连接

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

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

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


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

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

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

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


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

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

不可能发送授权头。

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

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

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