我试图在socket.io客户端发出连接请求时设置一个http标头。有办法做到这一点吗?
这就是我正在做的:
// server side
var io = socketio(server);
io.use(function (socket, next) {
// authorize using authorization header in socket.request.headers
});
// client side
var socket = io(); // i'm trying to set an authorization header in this http reqeust
有什么想法吗?谢谢。
如果您使用的是socket.io-client >= 1.4,则可以使用
extraHeaders
选项。
例如:
var socket = io("http://localhost", {
extraHeaders: {
Authorization: "Bearer authorization_token_here"
}
});
engine.io-client,是socket.io-client的后端,于2015-11-28
引入了
extraHeaders
支持。
有一种新方法可以做到这一点:https://socket.io/docs/v3/middlewares/。查看“发送凭据”部分。
// client
const socket = io(server, {
transports: ['websocket', 'polling', 'flashsocket'],
auth: {
token: 'abc'
}
});
// server
io.use((socket, next) => {
const token = socket.handshake.auth.token;
if (isValidJwt(token)){
next();
}else{
next(new Error("Socket authentication error"));
}
});
async function isValidJwt(token){
jwt.verify(token, secrets.jwt, function(err, decoded) {
if (err){
console.log(err);
return false;
}else{
//console.log(decoded);
return true;
}
});
}
似乎客户端不支持设置标头,因为并非所有传输都允许设置标头。
facundoolano 的这篇post详细介绍了一种身份验证解决方法,不需要将身份验证令牌放入查询字符串中。
他的解决方法模块可以在https://github.com/invisiblejs/socketio-auth找到。
让我想知道为什么在服务器端,socket.io 允许访问请求标头...
以下信息自 socket.io 1.0 起已被弃用
授权有两种方法:全局或命名空间(想想路由)。全局方法是通过
io.set('authorization', function (handshakeData, callback)
配置调用在服务器上设置的。
handshakeData对象包含以下信息:
{
headers: req.headers // <Object> the headers of the request
, time: (new Date) +'' // <String> date time of the connection
, address: socket.address() // <Object> remoteAddress and remotePort object
, xdomain: !!headers.origin // <Boolean> was it a cross domain request?
, secure: socket.secure // <Boolean> https connection
, issued: +date // <Number> EPOCH of when the handshake was created
, url: request.url // <String> the entrance path of the request
, query: data.query // <Object> the result of url.parse().query or a empty object
}
可以在此文档页面获取上述信息和更深入的解释。
自版本 2.0.0 / 2017-01-22 起,engine.io-client 支持
[feature] Allow extraHeaders to be set for browser clients in XHR requests (#519)
然而,此时 socket.io-client 尚未更新以支持此功能,因此几天后可能会让这个传奇结束,直到那时使用以下说明:https://facundoolano.wordpress.com/2014/10 /11/socket-io-no-query-strings 的更好身份验证/
“transportOptions”选项可用于在socket.io请求中发送额外的标头。我也在这里解释过:-
由于某种原因,只有当套接字服务器也是socket.io时才会收到这些请求标头。 例如,如果我连接到 python Websockets 服务器,我就无法进行身份验证。
对我有用的唯一解决方案是使用不同的 WebSocket 客户端,例如,
ws
工作正常。
import WebSocket from 'ws';
const socket = new WebSocket('wss://example.com/path', {
headers: {
Authorization: 'token'
},
});
简短回答:这是基于规范的 imposiburu...如果您只需要尽早传递信息...为什么不查询参数?
socket = io('localhost:5000', {
path: '/mySocketPath',
transports: ['websocket'],
query: {
token:'some-token-value'
}
})
参见@satpal-07 https://github.com/socketio/socket.io-client/issues/1356#issuecomment-810023635
如果您将令牌存储在 cookie 中,则只需提供
withCredentials: true,
选项即可。