Básicamente estaba buscando lo mismo. Específicamente, quería lo siguiente:
- Para usar express.js, que envuelve la capacidad de middleware de Connect
- Autenticación "basada en formulario"
- Control granular sobre qué rutas se autentican
- Una base de datos para usuarios / contraseñas
- Usar sesiones
Lo que terminé haciendo fue crear mi propia función de middleware check_auth
que paso como argumento a cada ruta que quiero autenticar. check_auth
simplemente verifica la sesión y, si el usuario no ha iniciado sesión, los redirige a la página de inicio de sesión, de la siguiente manera:
function check_auth(req, res, next) {
// if the user isn't logged in, redirect them to a login page
if(!req.session.login) {
res.redirect("/login");
return; // the buck stops here... we do not call next(), because
// we don't want to proceed; instead we want to show a login page
}
// the user is logged in, so call next()
next();
}
Luego, para cada ruta, me aseguro de que esta función se pase como middleware. Por ejemplo:
app.get('/tasks', check_auth, function(req, res) {
// snip
});
Finalmente, necesitamos manejar el proceso de inicio de sesión. Esto es sencillo:
app.get('/login', function(req, res) {
res.render("login", {layout:false});
});
app.post('/login', function(req, res) {
// here, I'm using mongoose.js to search for the user in mongodb
var user_query = UserModel.findOne({email:req.body.email}, function(err, user){
if(err) {
res.render("login", {layout:false, locals:{ error:err } });
return;
}
if(!user || user.password != req.body.password) {
res.render("login",
{layout:false,
locals:{ error:"Invalid login!", email:req.body.email }
}
);
} else {
// successful login; store the session info
req.session.login = req.body.email;
res.redirect("/");
}
});
});
En cualquier caso, este enfoque fue diseñado principalmente para ser flexible y simple. Estoy seguro de que hay numerosas formas de mejorarlo. Si tiene alguno, me gustaría mucho su opinión.
EDITAR: Este es un ejemplo simplificado. En un sistema de producción, nunca querrás almacenar y comparar contraseñas en texto plano. Como señala un comentarista, hay bibliotecas que pueden ayudar a administrar la seguridad de la contraseña.
omniauth
(rails) o pythonsocial-auth
. Los usuarios de PHP (y otros lenguajes de servidor web comunes) también deben sentirse libres de agregar su equivalente.