2012-08-31 14 views
20

Utilizzando Nodejs passaporto, mi stava testando che cosa succede quando si verifica una condizione di errore utilizzando il seguente codice:Nodejs passaporto autenticare callback non essere chiamato

passport.use(new LocalStrategy(
    function(username, password, done) { 
    // asynchronous verification, for effect... 
    process.nextTick(function() { 
     findByUsername(username, function(err, user) { 
    console.log('in auth function'); 
     return done('errortest'); 
     if (err) { return done(err); } 
     if (!user) { 
      return done(null, false, { message: 'Unknown user ' + username }); 
     } 
     if (user.password != password) { 
      return done(null, false, { message: 'Invalid password' }); 
     } 
     return done(null, user); 
     }) 
    }); 
    } 
)); 

app.get('/logintest', function(req, res, next) { 
console.log('before authenticate'); 
    passport.authenticate('local', function(err, user, info) { 
console.log('authenticate callback'); 
    if (err) { return res.send({'status':'err','message':err.message}); } 
    if (!user) { return res.send({'status':'fail','message':info.message}); } 
    req.logIn(user, function(err) { 
     if (err) { return res.send({'status':'err','message':err.message}); } 
     return res.send({'status':'ok'}); 
    }); 
    })(req, res, next); 
}); 

secondo l'itinerario/logintest username = bob & Password = s? Mi aspettavo di vedere nella console, "prima di autenticare", quindi "nella funzione di autenticazione", quindi "autenticare la richiamata", ma mostra solo i primi due seguiti da "errortest" e "errortest" viene visualizzato nel browser.

Ho anche provato return done({'message':'test'}); e "[oggetto oggetto]" è stato visualizzato nella console e nel browser.

Non funziona correttamente o mi manca qualcosa?

EDIT: Come per risposta di Jared Hanson, l'aggiunta di questa funzione del gestore di errore come il terzo argomento di app.get() mi permette di intercettare l'errore e restituire il JSON appropriata:

... 
    })(req, res, next); 
    }, 
    function(err, req, res, next) { 
    // failure in login test route 
    return res.send({'status':'err','message':err.message}); 
    }); 

risposta

14

Stai comprensione perfettamente, e funziona come previsto.

Se si verifica un errore, Passport immediatamente next() ha quell'errore. È possibile utilizzare il middleware di gestione degli errori (dettagli: http://expressjs.com/guide/error-handling.html) se si desidera gestire tale errore in modo personalizzato.

I callback personalizzati vengono principalmente utilizzati per gestire l'esito positivo o negativo dell'autenticazione (user == false). Errori, come la connettività DB, ecc., Non vengono passati al callback, a favore del middleware di gestione degli errori sopra descritto. Ho pensato di cambiare questo, ma non ho trovato una ragione convincente per. Ma, se hai un caso d'uso che non è coperto da quanto sopra, fammi sapere.

+1

Grazie per la risposta rapida. Sono abbastanza nuovo su node.js ma il caso d'uso sta effettuando l'accesso tramite una chiamata jquery ajax. Volevo restituire un oggetto json con lo stato: "ok" per il successo, "fail" per nome utente/password errati e "err" se si è verificato un errore. (Nota la modifica del codice che ho creato per il successo.) – KevinVictor

+0

Quindi, quando viene richiamato il callback personalizzato, err è sempre nullo? – KevinVictor

+0

Ha pubblicato un seguito sul problema GitHub, in modo da poter formattare meglio il codice. https://github.com/jaredhanson/passport-local/issues/15 –

4

bodyparser.json() stava causando il mio problema, ho riparato impostandolo a tratta (in particolare sulla rotta passaporto) in questo modo:

app.post('/login', bodyParser.urlencoded({ extended: true }), function (req, res, next) { 
      passport.authenticate('local', function (err, user, info) { 
       if (err) { return next(err) } 
       if (!user) { 
        console.log('bad'); 
        req.session.messages = [info.message]; 
        return res.redirect('/login') 
       } 
       req.logIn(user, function (err) { 
        console.log('good'); 
        if (err) { return next(err); } 
        return res.redirect('/'); 
       }); 
      })(req, res, next); 
    }); 
Problemi correlati