2013-03-11 3 views
10

Sto usando passport.js solo per gli accessi a Google, Facebook e Twitter.Passport.js non riesce a serializzare l'utente

Node.js v0.8.19 con express.js 3.1.0 e passportjs versione 0.1.16. (passport-facebook - 0.1.5, twitter - 0.1.4 passport-goolge-oauth - 0.1.5)

Tutto funziona per un po ', dopo un'ora circa dell'app in esecuzione passport.js interrompe la serializzazione l'utente nella sessione req.user.

Facebook e Google stanno ricevendo significa dati completi dal loro rispettivi api

passport.use(new FacebookStrategy({ 
    clientID: FACEBOOK_APP_ID, 
    clientSecret: FACEBOOK_APP_SECRET, 
    callbackURL: "http://localhost:3000/auth/facebook/callback" 
    }, 
    function(accessToken, refreshToken, profile, done) { 
     var temp = {} 
     temp.name = profile.displayName 
     temp.id = profile.id 
     console.log(temp) 
     return done(null, temp); 
})); 

Il console.log qui stamperà con successo id utente e il nome, ma dopo aver chiamato

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

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

serializzare e deserializzare sono tratto dal passaporto-facebook example.

L'utente non sarà collegato a req.user.

Twitter non viene mai così lontano, dopo il ritorno all'URL di callback, Twitter dà l'errore:

Error: failed to find request token in session 
[03/11 23:28:24 GMT]  at Strategy.OAuthStrategy.authenticate    

Nota: questi fallimenti avvenire solo dopo un periodo di tempo, il lavoro correttamente per un po '. Ecco perché penso che potrebbe essere un problema di memoria, come Im salvare la sessione in memoria invece di una cooke.

Questo è il mio espresso configurazione app

app.configure(function(){ 
    app.set('port', process.env.PORT || 8080); 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'jade'); 
    app.use(express.favicon()); 
    app.use(express.logger('dev')); 
    app.use(express.cookieParser()); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +  3600000), }})); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

ho guardato la mailing list, ecc, ma non riuscivo a trovare qualcosa di corrispondente questo problema. Ho controllato il mio localhost e su un server nodejitsu. Tutto funziona per un po ', poi fallisce.

+3

Né passport.serializeUser() o deserializeUser() sembrano funzionare mai. serializeUser() dovrebbe prendere un oggetto e serializzarlo in una stringa che può essere utilizzata in un cookie per identificare univocamente un utente. Di solito si fa chiamando 'done (null, user.id)'. deserializeUser dovrebbe prendere lo stesso id (da un cookie) e trovare l'insieme corretto di dati in un database. Con mongodb si potrebbe fare 'User.findById (id, function (err, user) {done (err, user);});' –

+0

Quindi devono essere stringhe? –

+0

[Qui] (https://github.com/jaredhanson/passport-facebook/blob/master/examples/login/app.js) nell'esempio passport-facebook hanno la stessa serializzazione e deserializzazione come faccio io. –

risposta

6

Non riesco ancora a capire perché il problema si sia verificato, ma l'ho risolto effettuando le seguenti operazioni.

Modifica

app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +  3600000), }})); 

a

app.use(express.cookieSession({ secret: 'tobo!', maxAge: 360*5 })); 

Penso che la serializzazione l'intero oggetto utente dovrebbe funzionare dal deserializeUser sarà solo passare di nuovo il cookie passato. Ma non serializzando l'intero oggetto utente sta funzionando.

passport.serializeUser(function(user, done) { 
    console.log('serializeUser: ' + user._id) 
    done(null, user._id); 
}); 

passport.deserializeUser(function(id, done) { 
    db.users.findById(id, function(err, user){ 
     console.log(user) 
     if(!err) done(null, user); 
     else done(err, null) 
    }) 
}); 

ho avuto a zero problemi da quando ho fatto questo.

+1

Non sono sicuro che questo sia effettivamente il problema, ma penso che 'maxAge' sul cookie debba essere il numero di secondi che il cookie dovrebbe durare, non il tempo effettivo che dovrebbe scadere (che è quello che hai messo lì) . – Will

25

Per prima cosa è necessario capire cosa sono per serializzare e deserializzare.

1) serializeUser prendere un oggetto utente e memorizzare qualsiasi informazione desiderata nella sessione, quando si restituisce done(null, user), come da prima domanda.

2) deserializeUser prendere le informazioni memorizzate nella sessione (inviato da cookieSession in ogni richiesta) e controlla se la sessione è ancora valido per un utente, e if(!err) done(null,user) è vero, mantiene l'utente nella sessione, dove else done(err,null) lo rimuove dalla sessione, reindirizzandoti a ciò che il tuo app.get('/auth/:provider/callback') invia all'utente dopo aver verificato se la sessione è scaduta o meno. Questo dovrebbe chiarire le cose per la tua seconda domanda.