看起来很容易添加自定义HTTP头到你的websocket客户端与任何HTTP头客户端支持这一点,但我不知道如何与web平台的websocket API。
有人知道怎么做到吗?
var ws = new WebSocket("ws://example.com/service");
具体来说,我需要能够发送HTTP授权标头。
看起来很容易添加自定义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
})
);
其他回答
更多的替代解决方案,但所有现代浏览器发送域cookie随着连接,所以使用:
var authToken = 'R3YKZFKBVi';
document.cookie = 'X-Authorization=' + authToken + '; path=/';
var ws = new WebSocket(
'wss://localhost:9000/wss/'
);
以请求连接头结束:
Cookie: X-Authorization=R3YKZFKBVi
更新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中不起作用)。
感谢德米特里·弗兰克给出的基本验证答案
我的情况:
我想连接到一个生产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。
所有未来调试器-直到今天,即15-07-21
浏览器也不支持向服务器发送客户标头,因此任何此类代码
import * as sock from 'websocket'
const headers = {
Authorization: "bearer " + token
};
console.log(headers);
const wsclient = new sock.w3cwebsocket(
'wss://' + 'myserver.com' + '/api/ws',
'',
'',
headers,
null
);
这在浏览器中是行不通的。这背后的原因是浏览器原生Websocket构造函数不接受头文件。
正如我上面所示,w3cwebsocket承包商接受头文件,因此很容易被误导。然而,这在node.js中是有效的。
从技术上讲,您将在协议升级阶段之前通过connect函数发送这些头文件。这在我的一个nodejs项目中是有效的:
var WebSocketClient = require('websocket').client;
var ws = new WebSocketClient();
ws.connect(url, '', headers);