插座建立之后socket.io认证 [英] socket.io authentication after socket established

查看:431
本文介绍了插座建立之后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?

我仍然可以保持认证,如果他们离开现场,回来?您可以通过Web接口通过一个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:

在用户的初始连接,创建一个cookie具有独特的会话ID,如前preSS会话中间件产生的。您将需要配置这些不要在会话结束时到期,虽然(否则会尽快为他们关闭浏览器过期)。

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设置时间,存储在与假(意味着用户已经由会话认证,但不被登录)的默认值的新对象

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。

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,并检查它在你的对象值为true。

Now, when receiving a new http request, read the cookie.sid, and check if its value in your object is true.

它应该看起来像下面这样:

It should look something like the following:

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天全站免登陆