Estou tentando estabelecer um mecanismo de login usando node.js, express e passport.js. O login em si funciona muito bem, também as sessões são armazenadas bem com o redis, mas eu tenho alguns problemas em redirecionar o usuário de onde ele começou antes de ser solicitado a autenticar.
por exemplo, o usuário segue o link http://localhost:3000/hidden
é redirecionado para, http://localhost:3000/login
mas quero que ele seja redirecionado novamente para http://localhost:3000/hidden
.
O propósito disso é, se o usuário acessar aleatoriamente uma página que ele precisa estar logado primeiro, ele será redirecionado para o site / login fornecendo suas credenciais e, em seguida, sendo redirecionado de volta para o site que tentou acessar anteriormente.
Aqui está minha postagem de login
app.post('/login', function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
if (err) {
return next(err)
} else if (!user) {
console.log('message: ' + info.message);
return res.redirect('/login')
} else {
req.logIn(user, function (err) {
if (err) {
return next(err);
}
return next(); // <-? Is this line right?
});
}
})(req, res, next);
});
e aqui meu método garantir; autenticado
function ensureAuthenticated (req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
que se conecta à /hidden
página
app.get('/hidden', ensureAuthenticated, function(req, res){
res.render('hidden', { title: 'hidden page' });
});
A saída html para o site de login é bastante simples
<form method="post" action="/login">
<div id="username">
<label>Username:</label>
<input type="text" value="bob" name="username">
</div>
<div id="password">
<label>Password:</label>
<input type="password" value="secret" name="password">
</div>
<div id="info"></div>
<div id="submit">
<input type="submit" value="submit">
</div>
</form>
Respostas:
Não sei sobre passaporte, mas faço isso da seguinte maneira:
Eu tenho um middleware que uso com
app.get('/account', auth.restrict, routes.account)
esse setredirectTo
na sessão ... então redireciono para / loginEntão,
routes.login.post
eu faço o seguinte:fonte
req.session.redirect_to = req.path
req.session.redirect_to = req.path
dentro de seu middleware de autenticação. Então leia e exclua nalogin.post
rota.Em seu
ensureAuthenticated
método, salve o url de retorno na sessão como este:Em seguida, você pode atualizar sua rota passport.authenticate para algo como:
fonte
req.session.returnTo = null;
Veja esta pergunta para obter informações adicionais sobre o logout padrão do passaporte, que, no exame da fonte, parece limpar apenas o session.user, e não a sessão inteira.req.path
eu usaria,req.originalUrl
pois é uma combinação de baseUrl e path, consulte a documentaçãoDê uma olhada em conectar-garantir-login , que funciona junto com o Passport para fazer exatamente o que você deseja!
fonte
Minha maneira de fazer as coisas:
GET / controlador de login :
Controlador POST / login :
Controlador POST / logout (não tenho certeza se está 100% ok, comentários são bem-vindos):
Limpa o middleware returnTo (limpa o returnTo da sessão em qualquer rota, exceto as rotas de autenticação - para mim, elas são / login e / auth /: provider):
Essa abordagem tem dois recursos :
fonte
Se você estiver usando o conectar-garantir-login, há uma maneira super fácil e integrada de fazer isso com o Passport usando o
successReturnToOrRedirect
parâmetro. Quando usado, o passaporte o enviará de volta ao URL originalmente solicitado ou retornará ao URL fornecido.https://github.com/jaredhanson/connect-ensure-login#log-in-and-return-to
fonte
As respostas @chovy e @linuxdan têm bug com não limpar
session.returnTo
se o usuário vai para outra página após o redirecionamento do login (isso não requer autenticação) e logins por meio dela. Portanto, adicione este código às suas implementações:Se você fizer algumas solicitações ajax da página de login, também poderá excluí-las.
Outra abordagem é usar o flash em
ensureAuthenticated
E então em GET login
Em vista adicionar campo oculto ao formulário de login (exemplo em jade)
Login no POST
Observe que redirectTo será limpo após o primeiro login GET com ele.
fonte
A maneira mais fácil (e adequada) de conseguir isso é a configuração
failureRedirect
e assuccessRedirect
opções .fonte
successRedirect
sendo usado na rota de retorno, mas o destino pretendido (ou seja,returnTo
acima) seria perdido, certo?