2012-06-12 6 views
6

Sto cercando di integrare il passport nel mio server nodejs utilizzando connect, ma non riesco a farlo correttamente. Tutte le guide/esempi usano expressJS, quindi ho fatto del mio meglio per riformattare il codice per lavorare con il mio codice, ma non riesco a farlo funzionare. Le parti correlate sono scritte sotto. Qualcuno ha qualche consiglio su quale potrebbe essere il problema? passport.authenticate() non sembra mai essere chiamato (almeno il messaggio console.log all'interno della richiesta di autenticazione di facebook non viene mai stampato). Al momento non sto salvando nulla in un database, quindi il problema dovrebbe essere qualcosa di veramente semplice che mi manca.Utilizzo di PassportJS con Connect for NodeJS per autenticare gli utenti di Facebook

L'unica cosa che viene in mente è il potenziale callback che ho per facebook, che è un url localhost (poiché sto ancora sviluppando questo localmente). Sono stato in grado di autenticarmi con facebook usando anyauth (da un'istanza puramente locale), ma sono passato a passportJS in quanto stavo riscontrando problemi diversi in cui sembrava che passportJS si rivolgesse.

passport = require('passport'); 
    fpass = require('passport-facebook').Strategy; 

passport.serializeUser(function(user,done){ 
    done(null, user); 
}); 
passport.deserializeUser(function(obj,done){ 
    done(null,obj); 
}); 

passport.use(new fpass({ 
     clientID:'facebook app id', 
     clientSecret:'facebook app secret', 
     callbackURL:'http://localhost:3000/auth/facebook/callback' 
    }, 
    function(accessToken, refreshToken, fbUserData, done){ 
     console.log('got here'); 
     return done(null,fbUserData); 
    } 
)); 



    function checkLoggedIn(req, res, next){ 
     console.log("req.user: " + req.user); 
     if(req.user) 
      next(); 
     else{ 
      console.log('\nNot LOGGED IN\n'); 
      if(req.socket.remoteAddress || req.socket.socket.remoteAddress == '127.0.0.1'){ 
       var folder,contentType; 
       console.log('req url = '+req.url); 
       if(req.url == '/'){ 
        folder = __dirname + '/landingPage.html'; 
        contentType = 'text/html'; 
       } 
       else if(req.url == '/auth/facebook'){ 
        passport.authenticate('facebook'); 
        return; 
       } 
       else if(req.url == '/auth/facebook/callback'){ 
        passport.authenticate('facebook', {failureRedirect: '/failbook', successRedirect:'/'}); 
        return; 
       } 
       if(folder){ 
        console.log('got to folder part\n\n'); 
        fs.readFile(folder, function(error, content){ 
         if(error){ 
         res.writeHead(500); 
         res.end(); 
         } 
         else{ 
         res.writeHead(200, {'Content-Type': contentType}); 
         res.end(content); 
         } 
        }); 
        } 
        else{ res.writeHead(500); res.end();} 
      } 
      else {res.writeHead(500); res.end();} 
     } 
    } 

    connect.createServer(
    connect.cookieParser(), 
    connect.bodyParser(), 
    connect.session({secret:'wakajakamadaka'}), 
    passport.initialize(), 
    passport.session(), 
    checkLoggedIn).listen(8888); 
    console.log('Server has started.'); 
} 

Qualcuno ha qualche consiglio o vedere un problema tecnico in quello che sto facendo? Le mie altre due alternative sono il passaggio a everyauth e la ricerca di cosa sta succedendo lì, o il passaggio a ExpressJS, ma preferirei non andare con nessuna di queste opzioni.

migliore,
Sami

risposta

8

passport.authenticate restituisce una funzione che viene in genere utilizzato nella catena middleware, che viene invocato con req e res da espresso.

funzionerà autonomo all'interno di altri middleware o un gestore di percorso, come ad esempio la funzione checkLoggedIn, ma si deve richiamare esplicitamente la funzione tornò con req, res, e next lasciarlo ottenere quanto richiesto.

else if(req.url == '/auth/facebook'){ 
    // NOTE: call the function returned to process the request 
    passport.authenticate('facebook')(req, res, next); 
    return; 
} 

Sembra buono altrimenti. Fammi sapere se questo ti mette in moto.


UPDATE

Jared mi ha aiutato un po 'al di fuori di StackOverflow, e abbiamo capito il problema completamente. Sto aggiornando questa risposta per includere le nuove informazioni che abbiamo trovato.


1) Un problema è chiaramente che il reindirizzamento() middleware esiste in veloce ma non in Connect (almeno non la versione corrente). Quando si utilizza la connessione, è necessario cambiare la linea 97 della authenticate.js nel modulo PassportJS da return res.redirect(options.successRedirect); a:

var redirect = function(redirectionURL){ 
    res.writeHead(302, {'location':redirectionURL}); 
    res.end();    
} 

return redirect(options.successRedirect); 

nota - il options.successRedirect sopra è la stessa della successRedirect nel codice funzione di callback. Questa sarebbe la riga passport.authenticate('facebook', {failureRedirect: '/failbook', successRedirect:'/'}); nel codice nella mia domanda.


2) L'altro è che sto usando il modulo di cluster nel mio app (non qualcosa che mostra nel mio frammento di codice di cui sopra). Ciò significa che i dati della sessione non vengono letti correttamente dall'app nodeJS, che ha causato i miei problemi. Questo problema interessa qualsiasi libreria che si basa sulle sessioni, inclusi tutti gli altri moduli di autenticazione che utilizzano le sessioni (ad esempio everyauth, connect-auth, ecc.) citerò Jared per una soluzione:

Quick reply: are you using cluster or spinning up multiple server instances?

If so, the built-in MemoryStore for the session won't work properly, and you need to switch to something like this: https://github.com/visionmedia/connect-redis

Or one of the other session stores listed here: https://github.com/senchalabs/connect/wiki

The reason is that you'll end up hitting a server which didn't serve the original request, and thus doesn't have that session information in its own memory. That sounds like what could be going on if deserializeUser isn't called 100% of the time.

Spero che questo aiuti chiunque lo rende qui!

+0

hmm sto diventando più lontano di prima, ma non funziona ancora abbastanza. ora sto registrando il callback da facebook. Sto controllando '/ auth/facebook/callback' con req.url.split ('?') [0] ora in modo che la callback si registri. aggiungendo a (req, res, next) dopo che la chiamata alla funzione ha causato un loop di reindirizzamento infinito. qualche idea? – thisissami

+0

Penso che dovrai usare il middleware 'connect.query()' nella configurazione del middleware 'createServer'. Passport prevede che 'req.query' venga popolato in molti casi, compreso il richiamo del codice di autorizzazione nella richiamata di Facebook. –

+0

quasi lì ... con un '(req, res, next)' aggiunto alla fine della chiamata di autenticazione callback, la funzione di risposta di Facebook viene raggiunta con i dati di Facebook appropriati. Tuttavia, ottengo un 'TypeError: Object # non ha alcun metodo 'redirect''. La riga di codice incriminata è 'return res.redirect (options.successRedirect);' on line 97 of authenticate.js. Qualche idea su quale potrebbe essere il problema? – thisissami

Problemi correlati