2016-03-27 32 views
11

Ho ricevuto 200 risposte per la richiesta di accesso, ma 401 per eventuali richieste di controllo dell'autorizzazione successive, perché deserializeUser non ha mai chiamato. Mi sono tuffato nella fonte del passaporto e ho notato che il passaporto controlla se esiste req._passport.session.user e se no non chiama deserializeUser.metodo passaporto deserializeUser mai chiamato

Ho cercato tra le altre domande su StackOverflow, sembra che abbia un caso specifico.

C'è solo tipo di strategia di autenticazione locale, io uso richiesta Ajax per effettuare richieste d'accesso, le impostazioni CORS configurate, http://localhost:8080 - frontend, http://localhost:3000 backend)

Io uso bodyParse, cookieParser, sessione espresso, passaporto inizializzare e le sessioni di passaporto . Express session secure: false configurato mentre eseguo richieste di autenticazione tramite http.

Puoi trovare il mio progetto qui (backend package.json è buono, quindi puoi usarlo, non ha dipendenze mancanti, per quanto riguarda il frontend non sicuro), almeno puoi controllare il codice lì.

backend https://github.com/rantiev/template-api Frontend https://github.com/rantiev/template-angular

configurazione della sessione Express e CORS è qui https://github.com/rantiev/template-api/blob/master/modules/appConfigure.js

var path = require('path'); 
var bodyParser = require('body-parser'); 
var session = require('express-session'); 
var cookieParser = require('cookie-parser'); 
var MongoStore = require('connect-mongo')(session); 

module.exports = function (app, express, config, mongoose) { 

    app.use(cookieParser()); 
    app.use(bodyParser.urlencoded({ 
     extended: true 
    })); 
    app.use(bodyParser.json()); 

    app.use(function (req, res, next) { 

     // Website you wish to allow to connect 
     res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080'); 

     // Request methods you wish to allow 
     res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); 

     // Request headers you wish to allow 
     res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, X-AUTHENTICATION, X-IP, Content-Type, Origin, Accept, Cookie'); 

     // Set to true if you need the website to include cookies in the requests sent 
     // to the API (e.g. in case you use sessions) 
     res.setHeader('Access-Control-Allow-Credentials', true); 

     // Pass to next layer of middleware 
     next(); 
    }); 

    /*app.use(function (req, res, next) { 
     console.log('coockie is:', req.cookies); 
    });*/ 

    app.use(session({ 
     saveUninitialized: false, 
     resave: false, 
     secret: config.sessionsSecretToken, 
     cookie: { 
      secure: false 
     }, 
     store: new MongoStore({ mongooseConnection: mongoose.connection }) 
    })); 

    app.use(express.static(path.join(__dirname, '..' , 'public'))); 

}; 

configurazione Passport è qui https://github.com/rantiev/template-api/blob/master/api/authentication/authenticationR.js

var passport = require('passport'); 
var LocalStrategy = require('passport-local').Strategy; 
var rememberMe = require('../../modules/rememberMe'); 
var createAccessToken = require('../../modules/createAccessToken'); 

var bcrypt = require('bcrypt-nodejs'); 

var UserM = require('../users/userM'); 

module.exports = function (app, mainRouter, role) { 

    passport.use(new LocalStrategy({ 
     usernameField: 'email', 
     passwordField: 'password' 
    }, function (username, password, done) { 

     UserM.findOneQ({email: username}) 
      .then(function(user){ 

       if (user && bcrypt.compareSync(password, user.password)) { 
        done(null, user); 
       } else { 
        done(null, false); 
       } 

      }) 
      .catch(function(err){ 
       done(err); 
      }); 

    })); 

    passport.serializeUser(function (user, done) { 

     console.log('serialize'); 

     if (user) { 
      createAccessToken(user, done); 
     } else { 
      done(null, false); 
     } 
    }); 

    passport.deserializeUser(function (token, done) { 

     console.log('deserialize'); 

     UserM.findOneQ({accessToken: token}) 
      .then(function(user){ 

       if (user) { 
        done(null, user); 
       } else { 
        done(null, false); 
       } 

      }) 
      .catch(function(err){ 
       done(err); 
      }); 

    }); 

    app.use(passport.initialize()); 
    app.use(passport.session()); 

    mainRouter.post('/me', passport.authenticate('local'), function (req, res) { 
     res.status(200).send(); 
    }); 

    mainRouter.get('/logout', function (req, res) { 
     req.logout(); 
     res.redirect('/'); 
    }); 

    mainRouter.get('/me', function (req, res) { 

     if (!req.user) { 
      res.status(401).send('Please Login!'); 
      return; 
     } 

     var currentUser = { 
      id: req.user._id, 
      role: req.user.role 
     }; 

     res.status(200).json(currentUser); 
    }); 

}; 
+0

Sto avendo lo stesso problema, hai risolto questo? – Jeffpowrs

+0

No, risponderà qui quando avrò una soluzione. Ha dato un timeout. Di gran lunga ho fatto tutto il possibile con quello, non funziona) – Rantiev

+0

Suppongo che la richiesta di accesso sia l'impostazione del cookie che viene poi restituito in una richiesta successiva e che il cookie ha il token di accesso che hai emesso. –

risposta

0

Hai provato maxAge?

app.use(express.session({ store: sessionStore, 
          cookie: { maxAge : 3600000 } //1 Hour 
          })); 
+0

sì, l'ho fatto. in realtà ho dimenticato qual è lo stato del problema. Se l'ho risolto o meno, sembra che ho aggiornato tutti i moduli oltre 1 anno e tutto ha funzionato. – Rantiev

1

Se si guarda nel tuo stack di chiamate e scoprire che deserializeUser non viene chiamato perché req._passport.session.user non è impostato, allora il vostro problema è il seguente. Le linee offensive sono nel modulo express-session:

if (!req.sessionID) { 
    debug('no SID sent, generating session'); 
    generate(); 
    next(); 
    return; 
} 

Se sessionID è impostato, generate non è mai chiamato:

store.generate = function(req){ 
req.sessionID = generateId(req); 
req.session = new Session(req); // THIS 
req.session.cookie = new Cookie(cookieOptions); 

if (cookieOptions.secure === 'auto') { 
    req.session.cookie.secure = issecure(req, trustProxy); 
} 
}; 

Ma è possibile avere req.sessionID set, mentre req.session è nullo, il che spiega req._passport.session.user essere nullo- req.session non è mai impostato.

Ho continuato a risalire ancora di più a quando è impostato req.sessionID, che, con i nuovi cookie, veniva talvolta impostato e talvolta no.

Perché? Non lo so, e mi piacerebbe che qualcuno indagasse ulteriormente, ma, in sostanza, la lezione è provare a utilizzare il modulo cookie-session.