套接字建立后的socket.io身份验证 [英] socket.io authentication after socket established

查看:47
本文介绍了套接字建立后的socket.io身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on a small multiplayer game. I'd like to introduce authentication. I'm using Node.js and Socket.io.

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

When the user arrives that the main page - I want them to join the game whether they are logged in or not - but they will be unable to do anything within it (only watch).

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

How could I then go about authenticating the user on the already open socket?

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

Could I maintain the authentication still if they left the site and came back? Can you pass a cookie through a web socket?

编辑

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

To further my question. One of the possible thoughts I've had is to provide the websocket connection, then when they try to login in, it passes username and password as a message to the websocket.

client.on('onLogin', loginfunction);

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

I could then take the username and password, check against the database, then take the session ID of the socket and pass it somewhere to say that session is authenticated to that user.

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

Is this secure? Could I still implement a cookie on the socket so they could come back? Is there any way within socket.io of stating that the socket is now authenticated instead of manually checking on each message received?

干杯

推荐答案

这实际上并不太难,但您以错误的方式接近它.一些事情:

This isn't actually too hard, but you're approaching it the wrong way. A couple things:

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

  1. You cannot set a cookie with socket.io; you can, however, get the cookie values of any connected client at any time. In order to set a cookie, you will have to send a new http response, meaning the user must first send a new http request (aka refresh or go to a new page, which it sounds is not a possibility for you here).

是的:socket.io 是安全的(就任何传输的数据而言).

Yes: socket.io is secure (to the extent that any transmitted data can be).

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

As such, you can do the following:

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

On the user's initial connection, create a cookie with a unique session ID, such as those generated from Express's session middleware. You will need to configure these not to expire on session end though (otherwise it will expire as soon as they close their browser).

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

Next you should create an object to store the cookie session IDs. Each time a new connect.sid cookie is set, store in your new object with a default value of false (meaning that the user has been authenticated by session, but not by logon)

在用户登录时,向服务器发送套接字发射,然后您可以在那里验证登录凭据,并随后更新您创建的会话 ID 对象,以读取当前套接字 ID 的 true(已登录).

On the user's login, send a socket emit to the server, where you can then authenticate the login credentials, and subsequently update the session id object you created to read true (logged in) for the current socket id.

现在,当收到一个新的 http 请求时,读取 cookie.sid,并检查它在您的对象中的值是否为真.

Now, when receiving a new http request, read the cookie.sid, and check if its value in your object is 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
    });

});

这篇关于套接字建立后的socket.io身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆