这实际上并不太难,但是您以错误的方式接近它。几件事:
你不能设置一个带有socket.io的cookie;但是,您可以随时获取任何已连接客户端的 cookie 值。为了设置 cookie,你必须发送一个新的 http 响应,这意味着用户必须首先发送一个新的 http 请求(也就是刷新或转到一个新页面,这听起来对你来说是不可能的)。
是的:socket.io 是安全的(在任何传输数据都可以的范围内)。
因此,您可以执行以下操作:
在用户的初始连接上,创建一个具有唯一会话 ID 的 cookie,例如从 Express 的会话中间件生成的那些。不过,您需要将它们配置为不会在会话结束时过期(否则它们会在关闭浏览器后立即过期)。
接下来,您应该创建一个对象来存储 cookie 会话 ID。每次设置新的 connect.sid cookie 时,将默认值 false 存储在新对象中(意味着用户已通过会话进行身份验证,但未通过登录)
在用户登录时,向服务器发送一个套接字发射,然后您可以在服务器上验证登录凭据,然后更新您创建的会话 id 对象以读取当前套接字 id 的 true(登录)。
现在,当接收到一个新的 http 请求时,读取 cookie.sid,并检查它在你的对象中的值是否为真。
它应该如下所示:
var express = require('express'),
http = require('http'),
cookie = require('cookie');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
app.use(express.cookieParser());
app.use(express.session({
secret: 'secret_pw',
store: sessionStore,
cookie: {
secure: true,
expires: new Date(Date.now() + 60 * 1000), //setting cookie to not expire on session end
maxAge: 60 * 1000,
key: 'connect.sid'
}
}));
var sessionobj = {}; //This is important; it will contain your connect.sid IDs.
//io.set('authorization'...etc. here to authorize socket connection and ensure legitimacy
app.get("/*", function(req, res, next){
if(sessionobj[req.cookies['connect.sid']]){
if(sessionobj[req.cookies['connect.sid']].login == true){
//Authenticated AND Logged in
}
else{
//authenticated but not logged in
}
}
else{
//not authenticated
}
});
io.sockets.on('connection', function(socket){
sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid'].login = false;
sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid'].socketid = socket.id;
socket.on('login', function(data){
//DB Call, where you authenticate login
//on callback (if login is successful):
sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid']] = true;
});
socket.on('disconnect', function(data){
//any cleanup actions you may want
});
});