2013-10-24 14 views
6

Negli ultimi giorni ho sviluppato il mio primo sistema di autenticazione login utente & tramite Passport.js. Stranamente, l'ho finito e funziona esattamente come previsto. Il problema è che, anche se ho letto molti articoli e controllato decine di esempi online, sembra che non capisca completamente il codice in sé. Non ho problemi a capire il processo che sta dietro e perché deve succedere in questo modo. Lo apprezzerei molto se potessi chiarire alcune parti del codice per me. Questo è il codice di lavoro, conservati nel mio file app.js:Passport.js Login utente e autenticazione

// Passport session setup 
passport.serializeUser(function (user, done) { 
    done(null, user._id); 
}); 

passport.deserializeUser(function (id, done) { 
    User.findById(id, function(err, user) { 
     done(err, user); 
    }); 
}); 

// Use the Local Strategy within passport 
passport.use(new LocalStrategy(function (username, password, done) { 
    User.findOne({ username: username }, function(err, user) { 
     if (err) { 
      return done(err); 
     } 

     if (!user) { 
      return done(null, false, { message: 'Unknown user: ' + username}); 
     } 

     user.comparePassword(password, function(err, isMatch) { 
      if (err) { 
       return done(err); 
      } 

      if (isMatch) { 
       return done(null, user); 
      } else { 
       return done(null, false, { message: 'Invalid Password' }); 
      } 
     }); 
    }); 
})); 

var app = module.exports = express(); 

app.configure(function() { 
    app.set('views', path.join(__dirname + '/views')); 
    app.set('view engine', 'html'); 
    app.engine('html', hbs.__express); 
    app.use(express.logger()); 
    app.use(express.cookieParser()); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.session({ secret: 'xxx' }));  
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(app.router); 
    app.use(express.static(path.join(__dirname + '/public'))); 

}); 

Sto usando MongoDB (User - Modello mangusta). Inoltre, per memorizzare le password nel database che sto usando attualmente bcrypt.

Penso che la parte più critica che non capisco qui è la funzione di callback fatta. Posso capire che semplicemente passa alcuni valori, e so che molto per capire che il primo parametro è l'errore e il secondo i dati. Tuttavia, non riesco a coglierlo completamente perché non ne ho specificatamente fornito uno come parametro. Ad esempio, se avessi una funzione come questa:

// Random Function 
var randomFunction = function (a, b, done) { 
    done(a, b); 
}; 

// Then I would call the randomFunction providing my own **done** 
randomFunction('Random', 'Words', function(a, b) { return a + b; }); 

Eppure, nel mio esempio io non sono quello che specifica la callback fatto. E 'semplicemente un parametro di funzione di callback richiesto o è la stessa della funzione successiva in un middleware normale come ad esempio:

function middleware (req, res, next) { 
    next(req.user); // pass the req.user to next middleware 
} 

Inoltre, da dove viene Passport.js impegnare l'utente che gestisce? Lo lega a req.user? E come posso passarlo a certe viste nell'ordine, ad esempio, per visualizzare il nome utente?

Non vedo l'ora di ricevere il vostro feedback!

Grazie!

risposta

3

Done callback

sguardo al codice di Local Strategy:

function Strategy(options, verify) { 
    ... 
    this._verify = verify; 
    ... 
} 

verify è la funzione che verrà utilizzato dalla strategia per verificare un utente ed è stata specificata qui:

passport.use(new LocalStrategy(function (username, password, done) { 
    // your verification code here 
})); 

In seguito nella strategia è possibile trovare il metodo authenticate che chiama funzione di verifica dal passo:

this._verify(username, password, verified); 

Quindi, è ora vedere dove username, password e done==verified provengono da. Più tardi nel tuo codice chiamerai la callback done con argomenti (err, user, info). In poche parole, è necessario done per completare la procedura asincrona di verifica dell'utente.

req.user e vista

Sì, hai ragione su req.user.Così si può passare le vostre opinioni in due modi:

  1. Come argomento di res.render funzione. See docs

    res.render('some-template', { name: req.user }); 
    
  2. Usa res.locals come una sorta di provider di contesto (ora oggetto utente sarà disponibile in tutti i punti di vista che sono definiti in app.router). See docs

    // before app.use(app.router); 
    app.use(function(req, res, next) { 
        res.locals.user = req.user; 
        next(); 
    }); 
    
+0

Grazie mille per il vostro feedback! A quanto ho capito, fatto è una funzione di callback utilizzata per restituire le informazioni dal middleware. Per informazione intendo i 3 parametri (err, utente, informazioni). Fondamentalmente, potrei considerare il callback fatto come (in un modo di alto livello) il ritorno di quel middleware specifico? –

+1

Se ho capito la tua domanda nel modo giusto, no. 'done' è usato solo per fornire alcuni dati al livello successivo. Il tuo codice di verifica verrà eseguito in modo normale dopo aver chiamato 'done()', ecco perché dovresti usare 'return done (err); 'per interrompere l'esecuzione del tuo codice di verifica. È un caso comune per roba asincrona. –

+0

Questo è quello che intendevo ^^ Penso di essere stato un po 'ambiguo nella mia risposta :) Grazie mille per il tuo feedback, lo apprezzo davvero! –

Problemi correlati