我正在使用Socket.io
并Express
制作一个聊天应用程序。
聊天是匿名的,我不想在任何数据库中保存任何内容。我可以考虑检查用户的 IP 地址并防止从同一 IP 地址再次登录,但我认为这不是一个好主意,因为人们使用共享 IP 地址在线。另一件事是会话 ID,但即使用户从浏览器中的不同选项卡登录,它也会发生变化。有没有不使用任何数据库的简单方法来做到这一点?最好不安装任何其他包/库?
express.session 中间件使用基于 cookie 的会话,默认情况下只存储在内存中而不是数据库中。如果用户打开新标签,基于 cookie 的会话不会改变。这篇文章在 SO 的其他地方被提到,作为使用 socket.io 的快速会话的一个很好的参考。通常,您只需在 socket.io ( sio.set('authorization', authCallback)
) 中授权时检查会话,然后您的应用程序可以使用户连接到正确的房间。
更新:(更具体地说明如何使用 cookie 阻止用户)
// Var to save if the user is connected or not
var connectedUsers = [];
sio.authorization(function(data, next){
var cookie = data.headers.cookie && data.headers.cookie.match(/auth=([^;]+)/);
cookie = cookie && cookie[1] || null;
if (cookie && connectedUsers.indexOf(cookie)){
next(null, false);
}
else {
connectedUsers.push(cookie);
next(null, cookie);
}
});
// Somewhere else
socket.on('disconnect', function (data) {
var cookie = data.headers.cookie && data.headers.cookie.match(/auth=([^;]+)/);
cookie = cookie && cookie[1] || null;
if(cookie) {
connectedUsers.splice(connectedUsers.indexOf(cookie), 1);
}
});
这是获取 cookie 值的一种非常基本的方法,但它对我有用。请注意,我没有时间尝试此解决方案,但原理应该有效。
这就是我所做的和为我工作的。这与安德烈亚斯的回答没有太大区别:
var MemoryStore = express.session.MemoryStore;
var sessionStore = new MemoryStore();
app.configure(function() {
//app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({
store: sessionStore,
secret: 'someSecret',
key: 'cookie.sid', maxAge: null }));
});
var sessionID;
var sessionArray = new Array();
var sessionIDs = new Array();
在我的“登录”功能中,我有:
sessionArray = socket.handshake.headers.cookie.split(" ");
sessionID = sessionArray[0].split("express.sid=").pop();
if(sessionIDs.indexOf(sessionID) > -1) {
io.sockets.socket(socket.id).emit('preventlogin', true);
}
else {
sessionIDs.push(sessionID);
// and do the rest
}
在“断开连接”时,我会:
var ind = sessionIDs.indexOf(sessionID);
sessionIDs.splice(ind, 1);