Utilizzo Passport per l'autenticazione nella mia app e utilizzo anche Express. Per riassumere il mio problema: mia funzionalità di accesso funziona bene inizialmente, ma dopo tempi di sessione qualsiasi dell'utente fuori, non gli utenti sono in grado di accedereScadenza cookie node.js Express Passport
Sto usando la strategia locale standard per l'autenticazione..
io includo come nudo esempio possibile in base alla mia messa a punto:
//-------------
//Set up authentication with Passport
//-------------
var userModel = require('./models/user')(db);
passport.use(new LocalStrategy(
function(username, password, done) {
var errorMessage = 'Incorrect username/password combination.';
userModel.GetUserByUsername(username, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: errorMessage });
}
user.validatePassword(password, function(isPasswordCorrect) {
if (!isPasswordCorrect)
{
return done(null, false, { message: errorMessage });
}
//Update with login date
userModel.UpdateUserWithLogin(username, user.currentLoginTime, function(err){
//if we have an error here, we should probably just log it
if(err)
{
console.log(err);
}
});
return done(null, user);
});
});
}
));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
userModel.GetUserByUsername(user._id, function(err, user) {
done(err, user);
});
});
//-------------
//Set up express and configure
//-------------
var sessionStore = new SkinStore(db);
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.engine('html', consolidate.swig);
app.set('view engine', 'html');
swig.init({
root: '.',
allowErrors: true, // allows errors to be thrown and caught by express instead of suppressed
autoescape: false});
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser("[mysecrethere]"));
app.use(express.session({ store: sessionStore,
cookie: { expires : new Date(Date.now() + 3600000) } //1 Hour
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(expressValidator);
app.use(express.static(path.join(__dirname, 'public')));
//Dynamic helpers
app.use(require('./helpers/DynamicHelpers'));
app.use(app.router);
});
app.get('/login', routes.login);
app.post('/login', passport.authenticate('local', {failureRedirect: '/login',
badRequestMessage: "Please enter username and password",
failureFlash: true }),
function(req, res) {
var targetUrl = req.session.pageAfterLogin;
delete req.session.pageAfterLogin;
res.redirect(targetUrl || '/account');
});
app.get('/account', IsAuthenticated, routes.account.show);
E la funzione di supporto IsAuthenticated:
function IsAuthenticated(req,res,next){
if(req.isAuthenticated())
{
next();
}
else
{
//save the requested page and then redirected
req.session.pageAfterLogin = req.url;
req.flash("error", "You must be logged in first!");
res.redirect('/login');
}
}
Cosa posso trovare per il debug è che, dopo il successo l'autenticazione (e dopo un cookie è scaduto), mi ha colpito questa logica (dall'alto):
function(req, res) {
var targetUrl = req.session.pageAfterLogin;
delete req.session.pageAfterLogin;
res.redirect(targetUrl || '/account');
}
Dove posso vedere che il "req" ha la sessione impostata correttamente, con le informazioni sul passaporto memorizzate correttamente. Quindi, si verifica il reindirizzamento, la nuova richiesta non contiene informazioni sulla sessione e ha un ID sessione completamente nuovo. Sospettavo che non fosse stato impostato alcun cookie sul client, e sembra essere il caso, il che dovrebbe spiegare la mancanza di sessioni coerenti.
Tuttavia, non riesco a capire perché non è stato impostato alcun nuovo cookie per. C'è qualcosa di sbagliato nel modo in cui è configurata l'app che indicherebbe perché questo sta accadendo?
Devo aggiungere che il riavvio dell'istanza Node.js corregge il problema, non è qualcosa che sarebbe tollerabile in produzione.
Grazie.
UPDATE: Mi sono imbattuto Fiddler per vedere cosa stava succedendo con HTTP/S traffico, e posso vedere che quando funziona inizialmente, sto diventando un set di cookie nel browser (ho provato diversi), che è poi passato al server su richieste successive.
Quando il non funziona, il browser non trasmette cookie al server e pertanto Nodo invia un'intestazione Set-Cookie che fornisce ogni volta un nuovo cookie. Finora non ho avuto fortuna a determinare la causa di questo.
Avete controllato che passport.deserializeUser viene eseguito, esiste quella user._id e che il modello trova l'utente? Anche serializeUser dovrebbe richiamare un id, non l'oggetto utente. –
Sono riuscito a testarlo (finalmente), e posso vedere che serializeUser ** è ** chiamato. Tuttavia, nei successivi reindirizzamenti, deserializeUser non viene eseguito. In serializeUser, l'utente è stato trovato correttamente, ma non sembra persistere. E lavorerò per serializzare user._id al posto dell'utente. L'avevo fatto in origine, ma ho cambiato per qualche motivo che ho dimenticato. – creativename