2012-06-26 13 views
6

tengo un conocimiento práctico de passport for node, pero no tiene por cosas tales como:biblioteca de autenticación con Node.js "señal persistencia" funcionalidad

  • generando una "persistencia token" (como en authlogic/session/session.rb#L35
  • generación de tokens perecederos para password restablece
  • remember me funcionalidad
  • la gestión de aquellas propiedades de conexión/desconexión en alguna clase de modelo, etc.

¿Hay alguna biblioteca que haya resuelto esto en la comunidad Node.js? Si hay algo tan sólido (o en camino a ser tan robusto) como Devise for Rails, eso sería perfecto, pero cualquier cosa que resuelva este problema de token funcionará igual de bien.

Lo loco es que muchos de los ejemplos están almacenando el usuario id en la sesión.

request.session['userId'] = user.get('id') 

Eso es solo pedir ser pirateado.

Debe ser algo como esto:

require.session['persistenceToken'] = App.User.generateRandomToken() 
+0

supongo que no es tan difícil de poner en práctica, sólo desearía que ya existía. –

+0

He creado una estrategia de "recuérdame": https://github.com/jaredhanson/passport-remember-me –

Respuesta

8

Una contraseña de una sola vez (token alias de un solo uso) estrategia para el restablecimiento de contraseñas es algo que voy a estar poniendo en práctica. Dada la arquitectura de Passport, esto puede ser fácilmente un módulo separado y no me sorprendería descubrir que alguien más ya ha implementado tal cosa.

Recordarme y la funcionalidad de token de persistencia también es algo que me gustaría apoyar. Preferiblemente, me gustaría que sea una estrategia separada también, pero puede necesitar un poco de soporte central. Si ese fuera el caso, algunas líneas adicionales en req.logIn (https://github.com/jaredhanson/passport/blob/master/lib/passport/http/request.js#L28) deberían ser capaces de cubrirlo.

En cuanto al almacenamiento de una identificación de usuario en la sesión, no veo ningún gran riesgo dado que, de forma predeterminada en Connect/Express, las propiedades de la sesión se almacenan completamente en el backend y se busca por un único sid que se establece en una cookie encriptada Un usuario malintencionado debería poseer tanto el sid único como el secreto de sesión para falsificar las solicitudes.

Mozilla está usando Passport como parte de su esfuerzo de identidad, para conectar BrowserID a otros proveedores que carecen de compatibilidad con BrowserID (consulte browserid-bigtent). Teniendo en cuenta sus requisitos, los desarrolladores pueden estar seguros de que Passport cumple con estrictos requisitos de seguridad. (La serialización de sesión en Passport es una responsabilidad de la aplicación, por lo que se puede usar un token aleatorio en lugar d sugerir que hacerlo es el enfoque menos aconsejable.)

En cuanto a la gestión de esas propiedades en un modelo, Passport está diseñado para ser completamente independiente del modelo/ORM. No tengo la intención de cambiar ese hecho alguna vez, ya que creo que esas decisiones se deben dejar a la aplicación (y Passport es más flexible al delegar esta responsabilidad). Dicho esto, creo que hay espacio para que otros módulos se construyan de manera independiente sobre Passport para proporcionar esta funcionalidad.

Dicho todo esto, creo que Passport es la más robusta de las soluciones de autenticación de Node.js existentes.Sus primeras tres solicitudes contribuirán en gran medida a que sea más, y deberían ser fáciles de lograr. Me encantaría colaborar para obtener estas funciones, así que no dude en ponerse en contacto conmigo.

Finalmente, en caso de que alguien tenga curiosidad, la autenticación API de primera clase está actualmente en proceso, en la rama authinfo. Sobre esta base, passport-http-oauth implementa estrategias de servidor OAuth, que se pueden combinar con oauthorize middlware como conjunto de herramientas para ensamblar servidores OAuth. Todavía no está completamente preparado, pero será otra característica efectiva de Passport cuando esté listo.

+0

estoy usando el pasaporte con la estrategia de autenticación local y me gustaría añadir el Recordarme functionaility. ¿De alguna manera puedo establecer la duración de la cookie en mi función serializeUser() porque tengo que hackear el núcleo? ¿O algo mas? – ragulka

2

Mientras tanto, algo así como lo siguiente debería ser suficiente. Ajuste según sea necesario para adaptarse a su aplicación y la duración deseada de la cookie. La comprobación del nombre de usuario & es una forma cursi de detectar un intento de inicio de sesión, pero funciona bastante bien con el pasaporte.

app.use(function(req, res, next) { 
    if(
      typeof(req.body.username) !== "undefined" 
      && typeof(req.body.password) !== "undefined" 
      ) { 
     if(req.body.remember == 1) { 
      req.session.cookie.maxAge = 365*24*60*60*1000; 
     } 
     else { 
      req.session.cookie.maxAge = 24*60*60*1000; 
     } 
    } 
    next(); 
}); 
+0

Me pregunto por qué no va a funcionar 'res.session.cookie.maxAge = null;' dentro de la declaración 'else'? Lo intenté, y si me conecto una vez con la opción "Recordarme" establecida en verdadero, todos los inicios de sesión posteriores también tendrán un conjunto de cookies persistentes, incluso si "Recordarme" está desactivado. – ragulka

+0

Me acabo de dar cuenta de que debería haber usado 'req.session.cookie.expires = false' en su lugar, publicaré una respuesta alternativa a esta pregunta. – ragulka

2

Aunque definitivamente me gustaría ver estas características en passport.js, todavía no están allí.

He creado un generador de símbolos aleatoria simple de usar con la función() serilizeUser passport.js, y modificado la respuesta de Justen sólo un poco para satisfacer mis necesidades. Básicamente, la única diferencia es que si la opción "recordar" no está configurada, la sesión durará mientras el navegador esté abierto.

Esta es mi serializador con el acceso aleatorio generador de símbolos. Estoy usando Mongodb y Mongoose, pero la implementación debería traducirse bastante bien en otros sistemas.

Básicamente, estoy consiguiendo el tiempo y añadiendo una cadena de 16 caracteres al azar a ella. Luego, en la función serializeUser(), verifico que ningún otro usuario tiene el mismo token (¡el token debe ser único!).

User.methods.generateRandomToken = function() { 
    var user = this, 
     chars = "_!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 
     token = new Date().getTime() + '_'; 
    for (var x = 0; x < 16; x++) { 
    var i = Math.floor(Math.random() * 62); 
    token += chars.charAt(i); 
    } 
    return token; 
}; 

Aquí está el serializador:

passport.serializeUser(function (user, done) { 

    var createAccessToken = function() { 
    var token = user.generateRandomToken(); 
    app.User.findOne({ accessToken: token }, function (err, existingUser) { 
     if (err) return done(err); 
     if (existingUser) 
     createAccessToken(); // Run the function again - the token has to be unique! 
     else { 
     user.set('accessToken', token); 
     user.save(function (err) { 
      if (err) return done(err); 
      return done(null, user.get('accessToken')); 
     }) 
     } 
    }); 
    }; 

    if (user._id) { 
    createAccessToken(); 
    } 
}); 

... y aquí está mi versión del middleware que se encarga de la funcionalidad "recuérdame". Preferiría que esto de alguna manera sea parte de la función serializeUser o passport.js core.

app.use(express.session({ secret: 'secret_key' })); 
app.use(function (req, res, next) { 
    if (req.method == 'POST' && req.url == '/login') { 
     if (req.body.remember) { 
     req.session.cookie.maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days 
     } else { 
     req.session.cookie.expires = false; 
     } 
    } 
    next(); 
}); 
app.use(passport.initialize()); 
app.use(passport.session()); 

Espero que ayude de alguna manera. Me tomó un par de horas para resolverlo y no estoy muy seguro de que este es el mejor forma de hacerlo, pero me funciona, por ahora.

+0

Sé que esto es muy viejo, pero ¿cómo es útil usar el middleware de sesión aquí? ¿No podemos simplemente saltearlo? –

Cuestiones relacionadas