socket建立后的socket.io认证

Chr*_*ans 14 authentication websocket node.js socket.io

我正在做一个小型多人游戏.我想介绍身份验证.我正在使用Node.js和Socket.io.

当用户到达主页面时 - 我希望他们加入游戏,无论他们是否登录 - 但他们将无法在其中执行任何操作(仅限于观看).

那我怎么可以在已打开的套接字上验证用户呢?

如果他们离开网站并回来,我可以保持身份验证吗?你可以通过网络套接字传递cookie吗?

编辑

进一步提问我.我有一个可能的想法是提供websocket连接,然后当他们尝试登录时,它将用户名和密码作为消息传递给websocket.

client.on('onLogin', loginfunction);
Run Code Online (Sandbox Code Playgroud)

然后我可以获取用户名和密码,检查数据库,然后获取套接字的会话ID并将其传递到某个地方,说该会话已经过该用户的身份验证.

这样安全吗?我还能在套接字上实现一个cookie,以便它们可以回来吗?在socket.io中是否有任何方法表明套接字现在已经过身份验证而不是手动检查收到的每条消息?

干杯

Ari*_*Ari 6

这实际上并不太难,但你正以错误的方式接近它.几件事:

  1. 你不能用socket.io 设置一个cookie; 但是,您可以随时获取任何连接客户端的cookie值.为了设置cookie,你必须发送一个新的http响应,这意味着用户必须首先发送一个新的http请求(也就是刷新或转到一个新的页面,这听起来不可能在这里).

  2. 是的:socket.io是安全的(在任何传输数据的范围内).

因此,您可以执行以下操作:

在用户的初始连接上,创建一个具有唯一会话ID的cookie,例如从Express的会话中间件生成的cookie.您将需要配置这些不会在会话结束时过期(否则它将在关闭浏览器后立即过期).

接下来,您应该创建一个对象来存储cookie会话ID.每次设置新的connect.sid cookie时,都会在新对象中存储默认值false(表示用户已通过会话进行身份验证,但未通过登录进行身份验证)

在用户登录时,将套接字发送到服务器,然后您可以在其中验证登录凭据,然后更新您创建的会话ID对象以读取当前套接字ID的真实(登录).

现在,当收到新的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
    });

});
Run Code Online (Sandbox Code Playgroud)