2012-01-06 20 views
14

Estoy trabajando en un pequeño juego multijugador. Me gustaría introducir la autenticación. Estoy usando Node.js y Socket.io.autenticación socket.io después del socket establecido

Cuando el usuario llega a la página principal - Quiero que se unan al juego si están conectados o no - pero no podrán hacer nada dentro de ella (solo mirar).

¿Cómo podría entonces autenticar al usuario en el socket ya abierto?

¿Puedo mantener la autenticación aún si abandonaron el sitio y regresaron? ¿Puedes pasar una cookie a través de un socket web?

EDITAR

Para aún más mi pregunta. Una de las posibles ideas que he tenido es proporcionar la conexión de websocket, luego, cuando intentan iniciar sesión, pasa el nombre de usuario y la contraseña como un mensaje al websocket.

client.on('onLogin', loginfunction); 

entonces podría tomar el nombre de usuario y contraseña, consulte la base de datos, a continuación, tomar el ID de sesión de la toma de corriente y pasar en algún lugar de decir que la sesión se autentica al usuario.

¿Esto es seguro? ¿Podría implementar una cookie en el socket para que puedan volver? ¿Hay alguna forma dentro de socket.io de indicar que el socket ahora está autenticado en lugar de verificar manualmente cada mensaje recibido?

Saludos

+0

¿Hay una manera tal de establecer que la conexión autenticada dentro socket.io una vez establecida la conexión y apretón de manos completa? El usuario podría proporcionar detalles de inicio de sesión cuando esté listo para una conexión existente, el servidor podría validar y devolver una ID de sesión única. La javascript del lado del cliente podría guardar una cookie para uso futuro. –

+0

Consulte [este artículo] (http://www.danielbaulig.de/socket-ioexpress/) sobre cómo autenticar las sesiones de socket.io. – fent

+0

Sí, ya he leído ese artículo. Aunque estoy bastante feliz configurando una cookie, no permite iniciar sesión en la misma página si el socket ya está abierto. ¿También se sufre presumiblemente si el usuario tiene cookies deshabilitadas? –

Respuesta

5

Esto no es realmente demasiado duro, pero lo aborda de la manera equivocada.Un par de cosas:

  1. No se puede establecer una cookie con socket.io; sin embargo, puede obtener los valores de las cookies de cualquier cliente conectado en cualquier momento. Para establecer una cookie, deberá enviar una nueva respuesta http, lo que significa que el usuario primero debe enviar una nueva solicitud HTTP (también conocida como actualizar o ir a una página nueva, lo que parece que no es una posibilidad para usted aquí).

  2. Sí: socket.io es seguro (en la medida en que los datos transmitidos pueden ser).

Como tal, puede hacer lo siguiente:

En conexión inicial del usuario, crear una cookie con un ID de sesión único, como los generados a partir de middleware sesión de Express. Deberá configurarlos para que no caduquen al finalizar la sesión (de lo contrario caducará tan pronto como cierren su navegador).

A continuación, debe crear un objeto para almacenar los ID de la sesión de cookie. Cada vez que se establece una nueva cookie connect.sid, almacene en su nuevo objeto un valor predeterminado de falso (lo que significa que el usuario ha sido autenticado por sesión, pero no por el inicio de sesión)

En el inicio de sesión del usuario, envíe un socket emitir al servidor, donde puede autenticar las credenciales de inicio de sesión y, posteriormente, actualizar el objeto de id de sesión que creó para leer verdadero (conectado) para el ID de socket actual.

Ahora, al recibir una nueva solicitud http, lea cookie.sid y compruebe si su valor en el objeto es verdadero.

Debe tener un aspecto como el siguiente:

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 
    }); 

}); 
+0

corrígeme si me equivoco, pero las sesiones que nunca expiran generalmente se consideran inseguras – brthornbury

+0

@Mozoby Mi código establece que la cookie caduque después de que haya transcurrido un cierto tiempo; no es indefinida. Lo hice porque la pregunta original parecía indicar que los usuarios que regresaban aún deberían haber iniciado sesión, lo que significa que no puedo dejar que caduquen las cookies en el navegador como lo hacen de forma predeterminada. – Ari

2

Chris, estoy no va a ser capaz de responder ya que no soy un experto en socket.io, pero tal vez pueda tratar de apuntar en otra dirección que le puede ayudar - y quitarle tiempo de desarrollo

Pero primero, un descargo de responsabilidad: trabajo para Realtime.co y no estoy tratando de hacer ningún tipo de publicidad. Trabajo estrechamente con los desarrolladores y solo estoy tratando de ayudarlo proporcionándole una solución lista para usar para su problema. Además, al ser un jugador, ¡no puedo evitar tratar de ayudar a la gente a obtener sus juegos!

Realtime usa una capa de autenticación/autorización en la que puede otorgar permisos de lectura/escritura a los canales. Cuando los usuarios ingresan al sitio web, puede darles permisos de solo lectura para el canal del juego y, una vez que inician sesión, pueden otorgarles permisos de escritura. Esto se puede hacer fácilmente haciendo una publicación de autenticación y reconectando al servidor (todo se puede hacer desde el lado del cliente). Lo haría desde el lado del servidor, sin embargo, para aumentar la seguridad.

Realtime tiene una API Node.js para que pueda integrarla fácilmente con su servidor. Como también tiene API para muchas otras plataformas (incluido el móvil) y todas funcionan de la misma manera, puedes hacer que tu juego funcione en múltiples plataformas sobre la misma capa de comunicación, al tiempo que tienes un control total sobre los canales.

Gracias por leer.

Editar:

Puede leer la documentación aquí para obtener más información: http://docs.xrtml.org/

Cuestiones relacionadas