Je n'ai pas de page de connexion mais j'ai plutôt un formulaire de connexion qui apparaît sur chaque page. Je souhaite rediriger les utilisateurs vers la même page sur laquelle ils se trouvaient, que l'authentification ait réussi ou non (avec les messages flash appropriés)
Prenez le code suivant:
app.post('/login', validateLogin, passport.authenticate('local-login'), function(req, res) {
var redirectUrl = '/';
if(req.body.to.length > 0){
redirectUrl = req.body.to;
}
console.log("THIS IS ONLY CALLED IF passport.authenticate() IS SUCCESSFUL");
res.redirect(redirectUrl);
});
Je ne vois le middleware final ci-dessus appelé que si l'authentification est réussie. Si cela échoue, alors passeport semble me rediriger vers/login sous la forme d'une demande d'obtention. Dans mon application, cette page n'existe pas.
Si je passe un objet options supplémentaire en tant que paramètre dans la fonction d’authentification du passeport, cela fonctionne:
app.post('/login', validateLogin, passport.authenticate('local-login', {
successRedirect : '/', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page. THIS IS JUST FOR TESTING TO SEE IF THE REDIRECT ON FAIL WORKS.
failureFlash : true, // allow flash messages
}
));
Mais ce faisant, je perds la possibilité de choisir où rediriger l'utilisateur. Il semble que le passeport prenne le contrôle sur l'endroit où l'utilisateur est redirigé en cas d'échec de l'authentification. Comment puis-je réparer cela? Ou est-ce un bug? L'authentification du passeport doit-elle être le dernier middleware de la chaîne si l'authentification échoue?
Ceci est mon appel de fonction de stratégie locale:
//LOCAL LOGIN
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
console.log("IN PASSPORT");
if(email.length == 0 || password.length == 0){
console.log("FIELDS ARE EMPTY");
return done(null, false, req.flash('loginMessage', 'Fill in all values.'));
}
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err){
return done(err);
console.log("db err");
}
// if no user is found, return the message
if (!user){
console.log("not user");
return done(null, false, req.flash('loginMessage', 'Incorrect details.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
if (!user.validPassword(password)){
console.log("invalid pw");
return done(null, false, req.flash('loginMessage', 'Incorrect details.')); // create the loginMessage and save it to session as flashdata
}
// all is well, return successful user
console.log("All OK");
return done(null, user);
});
}));
Vous pouvez utiliser un rappel d'authentification personnalisé, comme décrit dans le dernier paragraphe, http://passportjs.org/guide/authenticate/ .
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
// Redirect if it fails
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
// Redirect if it succeeds
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
Je courais dans le même problème où les appels de redirection, qui suivent avec succès Auth Facebook
.. n'étaient pas honorés.
Basé sur la stratégie 'locale' de passportJS - et un rappel gentil de celui de la réponse de @ ploutch ici ..
req.logIn(user, function(err) {
...
}
Pour Facebook, la configuration de cette route a fonctionné pour moi:
app.get(
'/auth/facebook/callback',
passport.authenticate
(
'facebook',
{ failureRedirect: '/fbFailed' }
),
function(req, res)
{
var user = myGetUserFunc(); // Get user object from DB or etc
req.logIn(user, function(err) {
if (err) {
req.flash('error', 'SOMETHING BAD HAPPEND');
return res.redirect('/login');
}
req.session.user = user;
// Redirect if it succeeds
req.flash('success', 'Fb Auth successful');
return res.redirect('/user/home');
});
}
);
Réponse complète, y compris:
Créez simplement une valeur redirectTo
dans votre middleware loginRequired
:
var loginRequired = function(req, res, next) {
if ( req.isAuthenticated() ) {
next();
return
}
// Redirect here if logged in successfully
req.session.redirectTo = req.path;
res.redirect('/login')
}
Et ensuite dans votre login POST:
router.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if ( err ) {
next(err);
return
}
// User does not exist
if ( ! user ) {
req.flash('error', 'Invalid email or password');
res.redirect('/login');
return
}
req.logIn(user, function(err) {
// Invalid password
if ( err ) {
req.flash('error', 'Invalid email or password');
next(err);
return
}
res.redirect(req.session.redirectTo || '/orders');
return
});
})(req, res, next);
});