2013-03-11 21 views
10

Używam passport.js tylko do logowania w Google, Facebooku i Twitterze.Passport.js nie nadaje się do serializacji użytkownika

Node.js v0.8.19 z plikiem express.js 3.1.0 i passportjs w wersji 0.1.16. (paszport-facebook - 0.1.5, twitter - 0.1.4 paszport-goolge-oauth - 0.1.5)

Wszystko działa dobrze przez jakiś czas, po godzinie aplikacji uruchamiającej passport.js przestaje serializować użytkownika do sesji req.user.

Facebook i Google otrzymują czyli pełnych danych z ich odpowiednimi 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); 
})); 

The console.log tutaj z powodzeniem drukować identyfikator użytkownika i nazwę, jednak po wywołaniu

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

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

serializacji i deserializacji są pobrane z paszportu-facebooka example.

Użytkownik nie zostanie przyłączony do req.user.

Twitter nigdy się tak daleko, po powrocie do url wywołania zwrotnego, twitter daje błąd:

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

Uwaga: te błędy się zdarzyć dopiero po pewnym czasie, prace właściwie na chwilę. To dlatego myślę, że może to być problem z pamięcią, jak Im zapisywanie sesji w pamięci zamiast gotować.

To mój express app konfiguracja

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

Mam spojrzał na listy itp, ale nie mógł znaleźć coś dopasowanie ten problem. Sprawdziłem na moim localhost i na serwerze nodejitsu. Wszystko działa przez jakiś czas, a następnie kończy się niepowodzeniem.

+3

Ani passport.serializeUser() ani deserializeUser() nie wyglądają tak, jakby mogły kiedykolwiek działać. serializeUser() powinien pobrać obiekt i przekształcić go w ciąg znaków, który może być użyty w pliku cookie do jednoznacznej identyfikacji użytkownika. Zwykle robi się to przez wywołanie 'done (null, user.id)'. deserializeUser ma przyjąć ten sam identyfikator (z pliku cookie) i znaleźć poprawny zestaw danych w bazie danych. Z mongodb możesz zrobić "User.findById (id, function (err, user) {done (err, user);));' –

+0

Więc muszą to być ciągi znaków? –

+0

[tutaj] (https://github.com/jaredhanson/passport-facebook/blob/master/examples/login/app.js) w przykładzie z paszportem na Facebooku mają ten sam szereg i deserializację jak ja. –

Odpowiedz

6

Nadal nie rozumiem, dlaczego pojawił się problem, ale rozwiązałem go, wykonując następujące czynności.

Zmiana

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

do

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

myślę, że szeregowania cały obiekt użytkownika powinien działać od deserializeUser będzie po prostu przejść z powrotem przekazany ciasteczko. Ale nie serializowanie całego obiektu użytkownika działa.

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

miałem zerowy problemy odkąd to zrobił.

+1

Nie jestem pewien, czy to rzeczywiście jest problem, ale myślę, że "maxAge" na ciasteczku ma być liczbą sekund, którą ciasteczko powinno trwać, a nie faktycznym czasem, który powinien wygasnąć (co tam umieściłeś) . – Will

25

Najpierw musisz zrozumieć, do czego służy serializacja i deserializacja.

1) serializeUser wziąć użytkownika obiektu i przechowywać wszystkie informacje, które chcesz w sesji, po powrocie done(null, user), jak na swoje pierwsze pytanie.

2) deserializeUser wziąć informacje przechowywane w sesji (wysłanego przez cookieSession na każde żądanie) i sprawdza, czy sesja jest nadal ważne dla użytkownika, a if(!err) done(null,user) jest prawdą, utrzymuje użytkownika w sesji, gdzie else done(err,null) usuwa go od sesji, przekierowując cię do tego, co twój app.get('/auth/:provider/callback') wysyła do użytkownika po sprawdzeniu, czy sesja jest przekroczona, czy nie. To powinno wyjaśnić kwestie dotyczące twojego drugiego pytania.

Powiązane problemy