2015-04-18 17 views
5

buduję SPA korzystając wyrazić, mangusta i passportjs.Pozostawanie uwierzytelniane po odświeżeniu strony za pomocą Passportjs

Stworzyłem prosty schemat dla mojego użytkownika:

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 
var passportLocalMongoose = require('passport-local-mongoose'); 

var User = new Schema({ 
    username: String, 
    password: String, 
    first_name: String 
}, { collection: 'users' }); 

User.plugin(passportLocalMongoose); 

mongoose.model('User', User); 

skonfigurowanego paszportu przy pomocy obiektu User który mangusta dał mi:

passport.use(new LocalStrategy(User.authenticate())); 
passport.serializeUser(User.serializeUser());   
passport.deserializeUser(User.deserializeUser()); 

i skonfigurowany moją aplikację do uwierzytelnienia użytkownika podczas nawigacji do ta trasa:

app.post('/login', passport.authenticate('local'), function(req, res, next) { 
    if (req.isAuthenticated()) { 
     return res.json({ state: 'success', user: { first_name: req.user.first_name } });  
    } 
    return res.json({ state: 'failure', message: 'cannot authenticate' }); 
}); 

Teraz jestem w stanie pomyślnie uwierzytelnić użytkownika. Przeglądarka zapisuje plik cookie z identyfikatorem sesji.

Mój problem polega na tym, że za każdym razem, gdy użytkownik odświeży stronę, paszport nie będzie deserializować użytkownika za pomocą identyfikatora sesji, co powoduje, że użytkownik jest nieuwierzytelniony.

Podczas uzyskiwania dostępu do obiektu req.user w katalogu głównym witryny dostaję undefined co mnie uświadomić sobie paszport nie deserializowania użytkownikowi prawidłowo:

app.use('/', function (req, res, next) { 
    console.log(req.user); // prints undefined.   

    next(); 
}); 

Jaka jest właściwa droga do przywrócenia użytkownikowi po odświeżeniu strony ?

+0

Mongoose należy deserializacji użytkownikowi, jeśli dzwonisz 'passport.deserializeUser (User.deserializeUser());' – Plato

Odpowiedz

4

Rozwiązaniem jest przechowywanie sesji w DB. Użyłem connect-mongo.

aplikacja.JS:

var mongoose = require('mongoose'); 
var expressSession = require('express-session'); 
var MongoStore = require('connect-mongo')(expressSession); 

mongoose.connect(db_url, function (err) { 
    if (err) { 
     console.log(err); 
    } 
}); 

app.use(expressSession({ 
    secret: process.env.SESSION_SECRET || 'keyboard cat', 
    resave: false, 
    saveUninitialized: false, 
    store: new MongoStore({ mongooseConnection: mongoose.connection }) 
})); 

po tym, req.isAuthenticated() zwraca true na każde żądanie nawet po odświeżeniu strony. (Dzięki app.use(passport.session()) który pojawia się przed każdym obsługi trasy)

app.use('/', function (req, res, next) { 
    if (req.isAuthenticated()) { 
     // returns true if a user already logged in. 
    } 
    next(); 
}); 
+1

var session = require ('express-session "); var MongoStore = require ('connect-mongo/es5') (express); app.use (express.session ({ sekret: process.env.SESSION_SECRET || 'to jest sekret', Ponownie Zapisz: false, saveUninitialized: fałszywe, sklep: nowy MongoStore ({mongooseConnection: mongoose.connection}) })); Czy nadal się wylogowujesz, gdy odświeżam? –

0

Patrząc na twój wpis, odgaduję, gdzie jest problem. W związku z tym wkleiłeś swój back-endowy kod expressjs, ale problem ma miejsce z przodu.

Wyobraź sobie sytuację, w której pracujesz nad normalnymi plikami javascript, dokonujesz pewnych zmian w wartościach zmiennych, korzystając z narzędzi Chrome dev firebug n all. Powiedzmy, że odświeżysz stronę, czy nadal widzisz tę samą edytowaną wartość w widoku? Bez prawa. Tak samo jest z twoim widokiem, tymczasowo przechowujesz dane użytkownika. Mimo że twój backend trzyma wartości w req.user, ale twój frontowy koniec go traci po odświeżeniu.

Więc trzeba zrobić jedną z dwóch poniżej:

  • przechowywać wartość w pliku cookie na udanym logowaniu i usunąć go, gdy wylogowany. Dzięki temu ciasteczko nigdy nie straci danych, nawet jeśli odświeżysz stronę. Dostęp do danych użytkowników z tego pliku cookie, kiedy trzeba go
  • połączeń API backend która zwraca wartość req.user na każdym stronie odświeżyć

Nie jestem pewien, co nakładka ramy używasz do SPA jeśli używasz AngularJS, możesz skorzystać z usługi cookieStore, która wykonuje to zadanie pięknie.

+0

Problemem jest to, że widzę plik cookie "sessionid" w mojej przeglądarce przy użyciu narzędzi dla deweloperów Chrome nawet po odświeżeniu strony. I tak, używam ** AngularJS ** – Matan

+0

Próbowałem wytłumaczyć ci możliwy przypadek. Wartość w interfejsie użytkownika zostanie wyczyszczona po odświeżeniu i musisz wywołać 'req.user', aby odzyskać. – NarendraSoni

+1

OK, więc prawdopodobnie tak nie jest, ponieważ widzę, że wartość jest wciąż żywa po odświeżeniu strony, a kiedy próbuję uzyskać dostęp do 'req.user', otrzymuję' undefined' – Matan