我有一个使用Node.js作为后端、普通JavaScript作为前端,并利用socket.io实现的应用程序。该应用程序拥有一个登录系统,目前是客户端在连接时立即发送其登录数据。
现在我想让登录数据随着握手数据一起发送,这样我就可以在连接时直接将用户登录,或在登录数据无效时拒绝授权。
我认为最好将我的附加数据放在握手数据的头部,则有任何想法如何实现呢?(如果可能的话,不修改socket.io,但如果这是唯一的方法,我也可以接受)
客户端:
//The query member of the options object is passed to the server on connection and parsed as a CGI style Querystring.
var socket = io("http://127.0.0.1:3000/", { query: "foo=bar" });
服务器端:
io.use(function(socket, next){
console.log("Query: ", socket.handshake.query);
// return the result of next() to accept the connection.
if (socket.handshake.query.foo == "bar") {
return next();
}
// call next() with an Error if you need to reject the connection.
next(new Error('Authentication error'));
});
您可以在客户端的connect()方法的第二个参数中传递一个查询参数,该参数将在服务器端的授权方法中可用。
我刚刚测试了一下。在客户端上,我有:
var c = io.connect('http://127.0.0.1:3000/', { query: "foo=bar" });
io.set('authorization', function (handshakeData, cb) {
console.log('Auth: ', handshakeData.query);
cb(null, true);
});
:!node node_app/main.js
info - socket.io started
Auth: { foo: 'bar', t: '1355859917678' }
您可以在客户端使用auth参数作为connect()的第二个参数来传递身份验证负载。
客户端:
io.connect("http://127.0.0.1:3000/", {
auth: {
token: "AuthToken",
},
}),
在服务器端,您可以使用socket.handshake.auth.token
来访问它。
服务器端:
io.use(function(socket, next){
console.log(socket.handshake.auth.token)
next()
});
这在v1.0.0中已经被更改。请参阅迁移文档
基本上,
io.set('authorization', function (handshakeData, callback) {
// make sure the handshake data looks good
callback(null, true); // error first, 'authorized' boolean second
});
变成:
io.use(function(socket, next) {
var handshakeData = socket.request;
// make sure the handshake data looks good as before
// if error do this:
// next(new Error('not authorized');
// else just call next
next();
});
socket.request
获取query
字段? - Harry Morenosocket.request._query
- Ciaran对于 socket.io v1.2.1,请使用以下内容:
io.use(function (socket, next) {
var handshake = socket.handshake;
console.log(handshake.query);
next();
});
这是我用来向nodejs和server.io服务器客户端发送查询数据的代码。
var socket = io.connect(window.location.origin, { query: 'loggeduser=user1' });
io.sockets.on('connection', function (socket) {
var endp = socket.manager.handshaken[socket.id].address;
console.log("query... " + socket.manager.handshaken[socket.id].query.user);
}
socket.manager.handshaken[socket.id].query.user
应该改为 socket.manager.handshaken[socket.id].query.loggeduser
。 - Valter Lorran// client
io.connect('localhost:8080', { query: 'foo=bar', extra: 'extra'});
// server
io.use(function(sock, next) {
var handshakeData = sock.request;
console.log('_query:', handshakeData._query);
console.log('extra:', handshakeData.extra);
next();
});
打印
_query: { foo: 'bar',
EIO: '3',
transport: 'polling',
t: '1424932455409-0' }
extra: undefined
io.connect('localhost:8080?foo=bar');
是我目前正在使用的。
虽然这是一个旧的线程,但假设您将JWT令牌/会话ID存储在会话cookie中(标准内容),当进行握手(socket.io-client)时,此信息默认传递给服务器。 通过Cookie获取握手的身份验证信息是否有问题?例如,通过中间件或on.connection获取身份验证信息。
io.on('connection', function(socket) {
// assuming base64url token
const cookieStr = socket.handshake.headers.cookie
const matchRes =
cookieStr == null
? false
: cookieStr.match(/my-auth-token=([a-zA-Z0-9_.-]+)/)
if (matchRes) {
// verify your jwt...
if ( tokenIsGood(matchRes[1]) {
// handle authenticated new socket
} else {
socket.emit('AUTH_ERR_LOGOUT')
socket.disconnect()
}
} else {
socket.emit('AUTH_ERR_LOGOUT')
socket.disconnect()
}
}
我现在正在使用它来完成一个项目,它运行良好。
我发现一个小问题,看不到 .loggeduser
io.sockets.on('connection', function (socket) {
var endp = socket.manager.handshaken[socket.id].address;
console.log("query... " + socket.manager.handshaken[socket.id].query.loggeduser);
// ↑ here
}