Eu estava basicamente procurando a mesma coisa. Especificamente, eu queria o seguinte:
- Para usar o express.js, que envolve o recurso de middleware do Connect
- Autenticação "baseada em formulário"
- Controle granular sobre quais rotas são autenticadas
- Um back-end de banco de dados para usuários / senhas
- Usar sessões
O que acabei fazendo foi criar minha própria função de middleware, check_auth
que passo como argumento para cada rota que quero que seja autenticada. check_auth
apenas verifica a sessão e, se o usuário não está logado, redireciona-o para a página de login, da seguinte forma:
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();
}
Então, para cada rota, garanto que essa função seja passada como middleware. Por exemplo:
app.get('/tasks', check_auth, function(req, res) {
// snip
});
Finalmente, precisamos realmente lidar com o processo de login. Isto é direto:
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("/");
}
});
});
De qualquer forma, essa abordagem foi projetada principalmente para ser flexível e simples. Tenho certeza que existem várias maneiras de melhorá-lo. Se você tiver algum, eu gostaria muito do seu feedback.
EDIT: Este é um exemplo simplificado. Em um sistema de produção, você nunca deseja armazenar e comparar senhas em texto sem formatação. Como comenta um comentarista, existem bibliotecas que podem ajudar a gerenciar a segurança da senha.
omniauth
(trilhos) ou pythonsocial-auth
. Os usuários de PHP (e outras linguagens comuns de servidores da web) devem se sentir à vontade para adicionar seus equivalentes também.