authentication - 建立套接字后的socket.io身份验证

标签 authentication node.js websocket socket.io

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

当用户到达主页时——无论他们是否登录,我都希望他们加入游戏——但他们将无法在其中做任何事情(只能观看)。

然后我该如何在已经打开的套接字上对用户进行身份验证?

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

编辑

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

client.on('onLogin', loginfunction);

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

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

干杯

最佳答案

这实际上并不太难,但是您以错误的方式接近它。几件事:

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

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

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

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

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

在用户登录时,向服务器发送一个套接字发射,然后您可以在服务器上验证登录凭据,然后更新您创建的 session 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
    });

});

关于authentication - 建立套接字后的socket.io身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8754849/

相关文章:

java - 授予对一个 GAE servlet 的公共(public)访问权限,但对所有其他资源使用身份验证?

Azure.Identity.CredentialUnavailableException问题

javascript - 同步连接到 Node js中的套接字

javascript - 使用 websocket 在浏览器和 java SE 项目之间传递数据

scala - PlayFramework 2.2 scala 关闭 WebSocket 连接

android - Login with Facebook option trigger 建议下载一个应用程序

php - 无法登录我的安全登录脚本 PHP 和 MySQL

javascript - JSON/Nodejs/swagger : Newlines not translated to multi-line in strings of express response displayed in swagger

mysql - Node.js Express 添加默认值 mysql

node.js - 如何测量使用 socket.io 内部传输的数据大小