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

有人知道怎么做到吗?

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

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


当前回答

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

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

其他回答

多亏了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...

不可能发送授权头。

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

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

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

你不能添加头,但是,如果你只需要在连接的时候向服务器传递值,你可以在url上指定一个查询字符串部分:

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

该URL是有效的,但当然,您需要修改服务器代码来解析它。

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


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

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

对于那些在2021年还在苦苦挣扎的人来说,Node JS全局web套接字类在构造函数中有一个额外的选项字段。如果你去WebSockets类的实现,你会发现这个变量声明。你可以看到它接受三个参数url,这是必需的,协议(可选),这是一个字符串,字符串数组或null。第三个参数是选项。我们的兴趣,一个对象和(仍然可选)。看到……

declare var WebSocket: {
    prototype: WebSocket;
    new (
        uri: string,
        protocols?: string | string[] | null,
        options?: {
            headers: { [headerName: string]: string };
            [optionName: string]: any;
        } | null,
    ): WebSocket;
    readonly CLOSED: number;
    readonly CLOSING: number;
    readonly CONNECTING: number;
    readonly OPEN: number;
};

如果你使用的是Node Js库,比如react,请使用react-native。这里有一个例子,你可以这样做。

 const ws = new WebSocket(WEB_SOCKETS_URL, null, {
    headers: {
      ['Set-Cookie']: cookie,
    },
  });

注意,对于协议,我传递了null。如果您正在使用jwt,您可以传递带有holder +令牌的授权标头

免责声明,这可能不支持所有的浏览器外的盒子,从MDN web文档中,你可以看到只有两个参数被记录。 看到https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket语法