我正在尝试使用 socket.io 验证WebSocket连接。
我的网络套接字可以从浏览器,Python或Node.js客户端接收连接。
在第一种情况下(浏览器),用户通过我的 Express.js 服务器进行身份验证,我只能use the session cookie,所以没问题。
但是,在第二种情况下(随机客户端)我需要自己处理身份验证。
我从 socket.io 文档中发现,有a hook用于在握手阶段授权连接。但是,客户端似乎无法添加自定义标头。看起来添加自定义数据的唯一方法是in the url query string。
这对我来说似乎并不安全,因为url是常见的记录内容,因此也会记录凭据。
另外,我想知道即使在握手期间连接是否安全,或者如果握手不是在ssl上,那么这样做是一个主要的安全问题。
嗯......基本上是安全问题。有人知道这样做的正确方法是什么?我是否真的必须在凭证中放置凭证,这是安全的吗?
答案 0 :(得分:0)
对于这样的努力,您需要将expressID挂钩到socketIO连接的sessionID。快递3是一个完全不同的故事,通常不那么容易。回到几个月前,我找到了一种方法。
//directories
var application_root = __dirname,
//general require
var express = require('express'),
connect = require('connect'),
http = require('http');
//create express app
var app = express();
//create sessionStore
var sessionStore = new connect.session.MemoryStore();
//setup sessionKey
var secretKey = 'superdupersecret';
//configure express
app.configure(function() {
//use body parser
app.use(express.bodyParser());
//override methods
app.use(express.methodOverride());
//cookies and sessions
app.use(express.cookieParser(secretKey));
app.use(express.session({
store: sessionStore,
secret: secretKey,
key: 'express.sid'
}));
//router
app.use(app.router);
});
//create the http server link to the new data http object of express 3
server = http.createServer(app);
//make server listen to 8080 and localhost requests
server.listen(8080, 'localhost', function() {
console.log('Express Server running and listening');
});
//bind socket.io to express server by listening to the http server object
var io = require('socket.io').listen(server);
//set the authorization through cookies
io.set('authorization', function(data, accept) {
//check if header data is given from the user
if (!data.headers.cookie) {
//return false if no cookie was given
return accept('Session cookie required!', false);
}
//parse cookie into object using the connect method
//NOTE: this line is a hack, this is due to the fact
//that the connect.utils.parseCookie has been removed
//from the current connect module and moved to an own
//instance called 'cookie'.
data.cookie = connect.utils.parseSignedCookies(require('cookie').parse(decodeURIComponent(data.headers.cookie)), secretKey);
//save session id based on exress.sid
data.sessionID = data.cookie['express.sid'];
//get associated session for this id
sessionStore.get(data.sessionID, function(err, session) {
if (err) {
//there was an error
return accept('Error in session store.', false)
} else if (!session) {
//session has not been found
return accept('Session not found', false);
}
//successfully got the session, authed with known session
data.session = session;
//return the accepted connection
return accept(null, true);
});
});
//connection handler for new io socket connections
io.sockets.on('connection', function(socket) {
//parse handshake from socket to io
var hs = socket.handshake;
//show session information
console.log('New socket connection with sessionID ' + hs.sessionID + ' connected');
});
//handle user disconnect and clear interval
io.sockets.on('disconnect', function() {
//show disconnect from session
console.log('Socket connection with sessionID ' + hs.sessionID + ' disconnected');
});
答案 1 :(得分:0)
所以看起来唯一的解决方案是在url查询字符串中添加您的身份验证数据。有open ticket允许其他可能性,但看起来开发人员只倾向于使用查询字符串。
答案 2 :(得分:0)
这对我有用:https://gist.github.com/jfromaniello/4087861。我不得不将socket.io-client package.json更改为使用xmlhttprequest版本1.5.0,它允许设置cookie头。我还必须改变使用socket.io xmlhttprequest:
的两个要求require('socket.io-client/node_modules/xmlhttprequest')
而不是
require ('xmlhttprequest');