Reputation: 53
I am integrating Passport in my NodeJs APP and the signup works, the login in itself works but when redirecting directly after logging in my Session.Passport is empty again and deserializeUser is never called. Maybe someone sees where I made a mistake or has a clue to what I did wrong.
First my settings for Passport isinde my app.js:
app.use(session({ cookie: { maxAge: 18000 },
secret: cryptoSecret,
resave: false,
saveUninitialized: true,
secure: false,
store: new memoryStore({checkPeriod: 86400000}),
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());
My Local Strategy etc:
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
console.log('Serialize User');
console.log(user);
console.log('---------------------------------------');
console.log(user._id);
console.log('---------------------------------------');
done(null, user._id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
console.log('deserialize Important!');
User.findById(id, function(err, user) {
console.log(err);
done(err, user);
});
});
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done(err);
// if no user is found, return the message
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
// if the user is found but the password is wrong
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, user);
});
}));
};
And here is my Login-route:
router.post('/', cors(), passport.authenticate('local-login', { failureRedirect : '/', failureFlash : true}), (req, res) => {
console.log('Login route! Authenticated?:', req.isAuthenticated(), ' Session:' , req.session);
req.logIn(req.session.passport.user, err => {
if(err) {
console.log(err);
}
res.redirect('/group');
});
});
I get the same behaviour when using successRedirect instead of the res.redirect :/
Session directly after authenticating:
And my Session when redirecting:
I tracked it down to my deserializeUser-function not beeing called and read so many SO entrys and other sites with no change. Getting a bit frustrated atm. First of all thank you all for reading and helping. I appreciate every bit of information that might help me with this. I hope you all have a nice day :)
Upvotes: 2
Views: 1549
Reputation: 2039
When you use passport.authenticate()
as a route middleware you don't need req.logIn()
because
this middleware invokes req.login()
automatically to establish a login session.
See req.login()
in the passport docs.
console.log('Login route! Authenticated?:', req.isAuthenticated(), ' Session:' , req.session);
shows the user is already authenticated.
I think the issue is that req.logIn()
doesn't succeed and it overwrites the session, so you get different
_expries
time in /login
and /group
. Also try increasing the maxAge
, you set it to 18 seconds
Try this
router.post('/login', cors(), passport.authenticate('local-login', {
failureRedirect: '/', failureFlash: true
}), (req, res) => {
// If this function gets called, authentication was successful.
console.log('Login route! Authenticated?:', req.isAuthenticated(), ' Session:', req.session);
res.redirect('/group');
})
Upvotes: 0
Reputation: 15797
It seems that the problem is that session is not working, since after redirection the passport
entry in your session is empty, it's normal that passport will not call deserializeUser
.
Your comment seems to confirm the problem is in session system.
A minimal working session system could be:
const session = require("client-sessions");
const cookieParser = require("cookie-parser");
const express = require("express");
const app = express();
app.use(cookieParser());
app.use(session({ cookie: { ephemeral: true }, cookieName: "session", secret: "keyboardcat" }));
If neither this makes work your session system, I suggest you to check if something is making cookies not working in your setup.
Upvotes: 3