2014-04-04 15 views
12

Giriş sayfası yok, ancak her sayfada görünen bir giriş formum var. Ben (uygun flaş mesajlarla) bakılmaksızın kimlik doğrulama başarılı olup olmadığını ait olduğumuzu aynı sayfadaNodejs ve PassportJs: kimlik doğrulama başarısız olursa, passport.authenticate çağrıldığında middleware yeniden yönlendirin

geri kullanıcıyı yönlendirmek istiyorum aşağıdaki kodu atın:

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); 
}); 

Ben sadece çağrıldığını yukarıda nihai ortakatmanını bakın kimlik doğrulaması geçilirse. Başarısız olursa pasaport, bana bir istek isteği şeklinde giriş/çıkış yapıyormuş gibi görünmektedir. Uygulamamda bu sayfa mevcut değil.

Bir ek seçenekler geçerseniz

o zaman bu işleri pasaport kimlik doğrulaması fonksiyonunda parametre olarak itiraz:

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 

} 


)); 

Ama bunu yaparken de ben yeniden yönlendirmek için yeri seçmek için yeteneklerini kaybederler. Pasaport, kimlik doğrulama başarısız olursa kullanıcının yönlendirildiği yerde kontrolü ele geçiriyor gibi görünüyor. Bunu nasıl düzeltebilirim? Yoksa bu bir hata mı? Kimlik doğrulaması başarısız olursa pasaport kimlik doğrulaması zincirdeki son ara katman olmalı mı?

Bu benim yerel strateji fonksiyon çağrısıdır: orada http://passportjs.org/guide/authenticate/ son paragrafta açıklandığı gibi

//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); 
    }); 

})); 

cevap

25

Özel bir kimlik doğrulama geri arama kullanabilirsiniz.

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); 
}); 
+0

Bu çalışır. Teşekkürler. (Kendi kendine not edin ... her zaman kılavuzu okuyun). – Paulie

+5

Savunmanızda, büyük bir konsept için oldukça ters bir el kitabıdır. (benzer sorunlarla karşılaşıyorum kendim ...) –

+0

Bunun için 'yerel strateji' eklememiz gerekiyor mu? Benim durumumda, bana yerel strateji bilinmeyen bir hata veriyor. – adi

3

Aynı sorunla koşuyordu nerede başarılı Facebook Auth

  • passport.authenticate izleyin yönlendirme-çağrılar, ('facebook', ..)

.. onurlandırılmamıştı.

'Yerel' passportJS Stratejisine dayanarak - ve bunun iyi bir hatırlatıcısı olan @ploutch's answer here ..İşten onu almak için anahtar gerçekleştirilen bu görüşmede gibi görünüyor:

req.logIn(user, function(err) { 
... 
} 

Facebook için bu rota kurulum benim için çalıştı:

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'); 
      });  
     } 
); 
+0

Bunu anlamıyorum. Eğer passport.authenticate ('facebook') ara katman yazılımı başarılı bir şekilde bittiyse ve bir sonraki anonim işleviniz çağrılırsa (bu aramanın tek yolu budur), o zaman zaten giriş yapmış olursunuz ve req.login() çağrısı gereksizdir. –

+0

@TimHardy Bu tür bir yapıyı kendimi çok zor/kafa karıştırıcı buldum; hiç bir kıvrık kimlik doğrulama yapıları hayranı değilim .. * grumble, grumble *. Buradaki çözüm için - yeterlikteki anahtar kelimeler * "bu rota kurulumu benim için çalıştı" * :) – gnB

0

Tam cevabı dahil:

  • Ara Katman u olmayacak
  • dönen değil değerleri redirectUrl
  • Flaş mesajları ayarlamak için sed

Sadece loginRequired katman bir redirectTo değer yaratmak:

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') 
} 

Sonra giriş POST içinde:

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); 
}); 
+0

Sadece anladığım kadarıyla, bir sonraki başarı ile çağrı yapmıyorsunuz, normalde bu kullanıcıyı pasaport katman yazılımıyla günlüğe kaydediyor. Bunun yerine, kullanıcıyı manuel olarak kaydeden ve özel bir yönlendirme uygulayan req.login çağırıyorsunuz. –

+0

Evet, bu doğru bir tanımlama. Belki '' .next() 'daha aptaldır? Ne düşünüyorsun? Kod çalıştığı sürece yayını düzenlemekten memnuniyet duyarsınız! – mikemaccana

İlgili konular