2013-07-26 13 views
5

Nie zostało to wcześniej zauważone, ponieważ w przypadku komunikacji klient-serwer nic nie wymaga uwierzytelniania przez XHR (jak na razie). Podczas implementowania niektórych testów integracyjnych tworzę prawdziwe żądania node-xmlhttprequest do prawdziwej instancji aplikacji. Użytkownik jest uwierzytelniany w pierwszym żądaniu i teoretycznie unikalny identyfikator użytkownika i inne istotne informacje są przechowywane w sesji (jak już powiedziałem, działa to dobrze dla prawdziwych klientów, którzy nie muszą potwierdzać swojej tożsamości przez XHR). Z jakiegoś powodu, mimo że kolejne żądania są uruchamiane z tym samym identyfikatorem sesji, nie mogę odzyskać sesji w kolejnych żądaniach, a zatem nie widzę, aby użytkownik był uwierzytelniany, a to prowadzi do niepowodzenia testów, w których oczekiwane zachowanie się nie zdarza, a protokół HTTP 401 UNAUTHORIZED wypełnia terminal.Aplikacja Express.js/Passport, która tworzy nową sesję dla każdego żądania, pomimo identyfikatora sesji w nagłówkach żądania

Widziałem kilka pytań, które wyglądają mniej więcej tak, ale ta "identyczna identyfikacja sesji" nie wydaje się być obecna wśród nich.

Czy muszę ręcznie dodawać nagłówki Set-Cookie do wszystkich żądań XHR? To okropne, musi być lepszy sposób!

Więc ludzie jak kod źródłowy, oto niektóre z testu, strzelające te wnioski:

// Ensure logged in before sending request, to verify that authorized 
// users encounter the expected behaviour. 
jQuery.post(domain+'/login', {email:'[email protected]', password:'12345678'}, 
function(data,x,y){ 
    data.should.equal("true") 
    jQuery.ajax({url:domain+'/event', type:"POST", 
    name: "TestEvent", location: "TestVille", 
    startDate: new Date('2013-09-01'), startTime: '6:45 pm', 
    description: "Test Event #1", success: state.success, 
    error: state.error, completed: state.completed 
    }) 
}) 

Zaloguj się dzieje, identyfikator użytkownika zostanie zapisana do sesji (`req.logIn() powinny to zrobić, i to nie zgłasza żadnych błędów), serializacja identyfikatora użytkownika nie zgłasza żadnych błędów i jestem bardzo zdezorientowany, dlaczego kolejne żądania korzystające z tego samego identyfikatora sesji nie są w stanie znaleźć zserializowanego identyfikatora użytkownika.

Generalnie nie jestem zaangażowany w tworzenie stron internetowych, więc może to być oczywiste dla niektórych osób, ale szukałem odpowiedzi przez cały dzień i po prostu nie mogłem jej znaleźć. Byłbym wdzięczny za wszelkie wskazówki i z przyjemnością przedstawię tyle kodów, ile jestem w stanie, aby zilustrować, na czym polega problem.

Kilka dodatkowych punktów kodu, które mogą być istotne:

serializacji/deserializacji identyfikatora użytkownika (aktualnie realizowanego w najprostszy sposób - jest bardzo wcześnie initiallization z warstwy pośredniej, a po initiallizing paszport passpot.session() A ten doskonale sprawdza się w przypadku wniosków innych niż XHR)

// Serialize user for passport session-store 
// Currently only serializing 'user_id' 
passport.serializeUser(function(user, done) { 
    done(null, user._id) 
}) 

// Deserialize user from session-store to provide 
// access to the User instance 
passport.deserializeUser(function(id, done) { 
    User.findById(id, function(err, user) { 
    done(err, user) 
    }) 
}) 

uwierzytelnianie użytkowników za pośrednictwem lokalnej strategii.

passport.use(new LocalStrategy({ 
    usernameField: "email", passwordField: "password", 
    passReqToCallback: true, failureFlash: true 
    }, 
    function(req, email, password, done) { 
    User.findByEmail(email, function(err, user) { 
     if(user) { 
     if(err) console.log(err) 
     if(user instanceof UserLocal) { 
      user.verifyPassword(password, function(err, match) { 
      if(err) console.log(err) 
      if(!match) { 
       return done(err, false, 
       "Username or password is incorrect.") 
      } 
      return done(null, user) 
      }) 
     } else { 
     var msg = "Account registered under " + user.providerName() 
       + ", please login using " + user.providerName() 
     return done(err, false, msg) 
     } 
    } else { 
     return done(err, false, "Username or password is incorrect.") 
    } 
    }) 
}) 

I wreszcie wnioski, które piszą do sesji w pierwszej kolejności:

function loginHelper(req, res, next) { 
    passport.authenticate('local', { 
    failureFlash:true, 
    failureRedirect: false, 
    successRedirect: false 
    }, 
    function(err, user, info) { 
    req.logIn(user, function(err) { 
     if(!err) err = {} 
     if(req.xhr) { 
     console.log(req.session) 
     res.status(200).end(err.message || "true") 
     } else { 
     if(err.message) req.flash('error', err.message) 
     else res.redirect('/') 
     } 
    }) 
    })(req, res, next) 
} 

wiem, istnieją pewne dziwne rzeczy jak wysyłanie statusu 200, niezależnie od statusu logowania, ale mogę potwierdzić, że w odcinkach użytkownik id jest zapisywane w sesji na żądanie XHR początkowego logowania i nie jest deserializowane w kolejnych żądaniach XHR.

Jak sądzę, wspomniałem, jestem stosunkowo niedoświadczony w tej dziedzinie i mogłem bardzo dużo wykorzystać. Każda pomoc będzie mile widziana, z góry dzięki.

+1

znaleźliście żadnych rozwiązań – Sushant

Odpowiedz

0

To pomaga mi Pierwsze

app.use(express.static(__dirname + '/public', { maxAge: oneDay })); 

i aktualizować funkcje nie wyzwalacz

passport.serializeUser((user, done) => { 
     var sessionUser = { id: user.dataValues.id, fio: user.dataValues.fio, email: user.dataValues.localemail, role: user.dataValues.role, login: user.dataValues.login, position: user.dataValues.position } 
     done(null, sessionUser) 
    }) 

    passport.deserializeUser((sessionUser, done) => { 
     // The sessionUser object is different from the user mongoose collection 
     // it's actually req.session.passport.user and comes from the session collection 
     done(null, sessionUser) 
    }) 

https://www.airpair.com/express/posts/expressjs-and-passportjs-sessions-deep-dive

Powiązane problemy