我正在研究一款小型多人游戏。我想介绍身份验证。我正在使用Node.js和Socket.io。
当用户到达该主页时-无论他们是否登录,我都希望他们加入游戏-但他们将无法在其中进行任何操作(仅观看)。
然后我该如何在已经打开的套接字上对用户进行身份验证?
如果他们离开站点并回来,我还能保持身份验证吗?您可以通过网络套接字传递Cookie吗?
编辑
进一步我的问题。我可能想到的一种方法是提供websocket连接,然后当他们尝试登录时,它将用户名和密码作为消息传递给websocket。
client.on('onLogin', loginfunction);
然后,我可以使用用户名和密码,对照数据库进行检查,然后获取套接字的会话ID,并将其传递到某个地方,以表明该会话已通过该用户的身份验证。
这样安全吗?我还能在套接字上实现cookie以便它们回来吗?socket.io中是否有任何方法说明套接字现在已通过身份验证,而不是手动检查收到的每条消息?
干杯
这实际上并不难,但是您正以错误的方式进行处理。几件事:
您不能使用socket.io 设置 cookie;但是,您可以随时获取任何已连接客户端的cookie值。为了设置cookie,您将必须发送一个新的http响应,这意味着用户必须先发送一个新的http请求(又名刷新或转到新页面,这听起来对您而言不可能)。
是的:socket.io是安全的(只要可以传输任何数据即可)。
因此,您可以执行以下操作:
在用户的初始连接上,创建具有唯一会话ID的cookie,例如从Express的会话中间件生成的cookie。但是,您将需要配置它们,使其在会话结束时不过期(否则,它们将在关闭浏览器后立即过期)。
接下来,您应该创建一个对象来存储cookie会话ID。每次设置新的connect.sid cookie时,都将其默认值存储在新对象中(这意味着该用户已通过会话而非登录进行了身份验证)
在用户的登录名上,向服务器发送套接字发出消息,然后您可以在其中验证登录凭据,然后更新您创建的会话ID对象,以使当前套接字ID读为true(登录)。
现在,当接收到新的http请求时,读取cookie.sid,并检查其在对象中的值是否为true。
它看起来应该如下所示:
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 }); });