Próbuję ustanowić mechanizm logowania przy użyciu node.js, express i passport.js. Samo logowanie działa całkiem nieźle, również sesje są ładnie przechowywane w redis, ale mam pewne problemy z przekierowaniem użytkownika do miejsca, z którego zaczął, zanim zostanie poproszony o uwierzytelnienie.
np. użytkownik podąża za odsyłaczem, http://localhost:3000/hidden
a następnie przekierowywany jest na adres, http://localhost:3000/login
ale chcę, aby został ponownie przekierowany z powrotem http://localhost:3000/hidden
.
Ma to na celu, jeśli użytkownik uzyskuje losowy dostęp do strony, na którą musi być najpierw zalogowany, zostanie przekierowany do witryny / login, podając swoje dane uwierzytelniające, a następnie z powrotem do witryny, do której wcześniej próbował uzyskać dostęp.
Oto mój wpis logowania
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);
});
i tutaj moja metoda zapewniająca uwierzytelnienie
function ensureAuthenticated (req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
który jest zaczepiany na /hidden
stronie
app.get('/hidden', ensureAuthenticated, function(req, res){
res.render('hidden', { title: 'hidden page' });
});
Dane wyjściowe html dla witryny logowania są dość proste
<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>
Odpowiedzi:
Nie wiem o paszporcie, ale tak to robię:
Mam wykorzystania middleware I z
app.get('/account', auth.restrict, routes.account)
tym, że zestawyredirectTo
w sesji ... wtedy przekierowanie do / loginNastępnie
routes.login.post
wykonuję następujące czynności:źródło
req.session.redirect_to = req.path
req.session.redirect_to = req.path
wewnątrz swojego oprogramowania pośredniego uwierzytelniania. Następnie przeczytaj go i usuń wlogin.post
trasie.W swojej
ensureAuthenticated
metodzie zapisz zwrotny adres URL w sesji w następujący sposób:Następnie możesz zaktualizować swój paszport. Uwierzytelnić trasę na coś takiego:
źródło
req.session.returnTo = null;
Zobacz to pytanie, aby uzyskać dodatkowe informacje o domyślnym wylogowaniu z paszportu, które, po zbadaniu źródła wydaje się czyścić tylko sesję użytkownika, a nie całą sesję.req.path
chciałbym użyćreq.originalUrl
, ponieważ jest połączeniem baseURL i ścieżki, patrz dokumentacjaSpójrz na connect-sure-login , który działa razem z paszportem, aby robić dokładnie to, co chcesz!
źródło
Mój sposób robienia rzeczy:
GET / login kontroler:
Kontroler POST / logowania :
Kontroler POST / wylogowania (nie jestem pewien, czy jest 100% ok, komentarze są mile widziane):
Clear returnTo middleware (czyści returnTo z sesji na dowolnej trasie z wyjątkiem tras autoryzacji - dla mnie są to / login i / auth /: provider):
To podejście ma dwie cechy :
źródło
Jeśli korzystasz z connect-sure-login, istnieje bardzo łatwy, zintegrowany sposób na zrobienie tego z Passport przy użyciu
successReturnToOrRedirect
parametru. W przypadku użycia paszport odeśle Cię z powrotem na pierwotnie żądany adres URL lub z powrotem na podany adres URL.https://github.com/jaredhanson/connect-ensure-login#log-in-and-return-to
źródło
Odpowiedzi @chovy i @linuxdan mają błąd polegający na braku czyszczenia,
session.returnTo
jeśli użytkownik przejdzie do innej strony po przekierowaniu logowania (to nie wymaga uwierzytelnienia) i zaloguje się przez nią. Więc dodaj ten kod do ich implementacji:Jeśli wykonujesz jakieś żądania AJAX ze strony logowania, możesz je również wykluczyć.
Innym sposobem jest użycie lampy błyskowej w
ensureAuthenticated
A następnie w GET login
W widoku dodaj ukryte pole do formularza logowania (przykład w jade)
Logowanie POST
Zauważ, że redirectTo zostanie wyczyszczone po pierwszym zalogowaniu GET.
źródło
Najłatwiejszym (i właściwie) sposobem osiągnięcia tego jest ustawienie
failureRedirect
isuccessRedirect
opcje .źródło
successRedirect
że jestem używany na trasie powrotnej, ale wtedy zamierzony cel (tj.returnTo
Powyżej) zostałby utracony, prawda?