Websockets 客户端 API 中的 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");
当我在服务器端的代码收到具有非空用户名和空密码的基本授权标头时,它会将用户名解释为令牌。
发送授权标头是不可能的。
附加令牌查询参数是一个选项。但是,在某些情况下,将您的主登录令牌以纯文本形式作为查询参数发送可能是不可取的,因为它比使用标头更不透明,并且最终会被记录到任何地方。如果这给您带来了安全问题,另一种方法是将辅助 JWT 令牌仅用于 Web 套接字内容。
创建用于生成此 JWT 的 REST 端点,当然只能由使用您的主要登录令牌(通过标头传输)进行身份验证的用户访问。Web 套接字 JWT 的配置可以与您的登录令牌不同,例如具有更短的超时,因此作为升级请求的查询参数发送更安全。
为在 上注册 SockJS eventbusHandler 的同一路由创建一个单独的 JwtAuthHandler。确保首先注册您的身份验证处理程序,以便您可以根据您的数据库检查 Web 套接字令牌(JWT 应该以某种方式链接到后端的用户)。
当您想使用 JavaScript WebSockets API 建立 WebSockets 连接时,您不能发送自定义标头。您可以Subprotocols
通过使用第二个 WebSocket 类构造函数来使用标头:
var ws = new WebSocket("ws://example.com/service", "soap");
然后您可以使用Sec-WebSocket-Protocol
服务器上的密钥获取子协议标头。
还有一个限制,您的子协议标头值不能包含逗号 ( ,
) !