我试图在Node.js中使用Socket.IO,并试图让服务器为每个Socket.IO客户端提供一个标识.由于套接字代码超出了http服务器代码的范围,因此它无法轻松访问发送的请求信息,因此我假设它需要在连接期间发送.什么是最好的方法
1)通过Socket.IO获取有关谁连接的信息
2)验证他们说自己是谁(我目前正在使用Express,如果这让事情变得更容易)
使用connect-redis并将redis作为所有经过身份验证的用户的会话存储.确保在身份验证时将密钥(通常为req.sessionID)发送给客户端.让客户端将此密钥存储在cookie中.
在套接字连接上(或以后的任何时间)从cookie中获取此密钥并将其发送回服务器.使用此密钥以redis格式获取会话信息.(GET键)
例如:
服务器端(使用redis作为会话存储):
req.session.regenerate...
res.send({rediskey: req.sessionID});
客户端:
//store the key in a cookie
SetCookie('rediskey', <%= rediskey %>); //http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx
//then when socket is connected, fetch the rediskey from the document.cookie and send it back to server
var socket = new io.Socket();
socket.on('connect', function() {
var rediskey = GetCookie('rediskey'); //http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx
socket.send({rediskey: rediskey});
});
服务器端:
//in io.on('connection') io.on('connection', function(client) { client.on('message', function(message) { if(message.rediskey) { //fetch session info from redis redisclient.get(message.rediskey, function(e, c) { client.user_logged_in = c.username; }); } }); });
我也很喜欢pusherapp做私人频道的方式.
Pusher生成一个唯一的套接字ID并将其发送到浏览器.这将通过AJAX请求发送到您的应用程序(1),该请求授权用户针对您现有的身份验证系统访问该通道.如果成功,您的应用程序会向使用Pusher secret签名的浏览器返回授权字符串.这是通过WebSocket发送给Pusher的,如果授权字符串匹配,则完成授权(2).
因为socket.io
每个套接字也有唯一的socket_id.
socket.on('connect', function() { console.log(socket.transport.sessionid); });
他们使用签名授权字符串来授权用户.
我还没有反映过这个socket.io
,但我认为它可能是非常有趣的概念.
我知道这有点旧,但对于未来的读者,除了解析cookie和从存储中检索会话的方法(例如passport.socketio)之外,您还可以考虑基于令牌的方法.
在这个例子中,我使用非常标准的JSON Web Tokens.您必须向客户端页面提供令牌,在此示例中,假设一个返回JWT的身份验证端点:
var jwt = require('jsonwebtoken'); // other requires app.post('/login', function (req, res) { // TODO: validate the actual user user var profile = { first_name: 'John', last_name: 'Doe', email: 'john@doe.com', id: 123 }; // we are sending the profile in the token var token = jwt.sign(profile, jwtSecret, { expiresInMinutes: 60*5 }); res.json({token: token}); });
现在,您的socket.io服务器可以配置如下:
var socketioJwt = require('socketio-jwt'); var sio = socketIo.listen(server); sio.set('authorization', socketioJwt.authorize({ secret: jwtSecret, handshake: true })); sio.sockets .on('connection', function (socket) { console.log(socket.handshake.decoded_token.email, 'has joined'); //socket.on('event'); });
socket.io-jwt中间件期望查询字符串中的令牌,因此从客户端您只需在连接时附加它:
var socket = io.connect('', { query: 'token=' + token });
我在这里写了一个关于这个方法和cookie的更详细的解释.