passport: req.user is undefined, passport not working with Express 4.0
I use passport@0.2.0 and passport-local@1.0.0.
req.user is alway undefined and so req.isAuthenticated() also not working.
Here is my express-setup:
var env = process.env.NODE_ENV || 'development';
var path = require('path'),
expressValidator = require('express-validator'),
config = require('../config/config')[env],
RedisStore = require('socket.io/lib/stores/redis'),
redis = require('socket.io/node_modules/redis'),
pub = redis.createClient(),
sub = redis.createClient(),
client = redis.createClient(),
utils = require('connect').utils,
cookieParser = require('cookie-parser');
bodyParser = require('body-parser'),
expressSession = require('express-session'),
compress = require('compression'),
morgan = require('morgan'),
errorHandler = require('errorhandler'),
methodOverwrite = require('method-override');
module.exports = function (app, passport, express, io) {
var RedisSessionStore = require('connect-redis')(expressSession);
var redisSessionStore = new RedisSessionStore(config.redis.sessions);
app.use(morgan());
app.use(cookieParser());
app.use(methodOverwrite());
app.use(bodyParser({ keepExtensions: true, uploadDir: config.files.upload.path, limit: config.files.upload.size }));
app.use(expressValidator());
app.use(expressSession({
secret : 'foo',
cookie : {
expires: false,
domain: config.cookie.domain
},
store: redisSessionStore
}));
app.use(passport.initialize());
app.use(passport.session());
// response static files
if(env == 'development'){
app.use(compress({
threshhold: 512
}));
app.use('/', express.static(path.join(__dirname, '../../frontend')));
app.use(errorHandler({ dumpExceptions: true, showStack: true }));
}
if(env == 'production'){
app.use(errorHandler());
app.enable('trust proxy');
};
}
… and passport-setup:
var LocalStrategy = require('passport-local').Strategy,
User = require('../model/User');
module.exports = function (passport) {
// serialize sessions
passport.serializeUser(function(user, done) {
var sessionData = {};
sessionData.user = user._id;
// store workingAt to build socket.io rooms
if(user.workingAt){
sessionData.workingAt = user.workingAt;
}
done(null, sessionData);
});
// deserialize sessions
passport.deserializeUser(function(sessionData, done) {
User.findById(sessionData.user, function (error, user) {
if(error){
done(error);
} else {
done(null, user);
}
})
});
// use local strategy
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
User.checkCredentials({email: email, password: password}, function(error, user){
if(error) {
return done(error);
} else {
return done(null, user);
}
});
}
))
EDIT: I try to find the reason of that bug and its seems its related to express-session. On every request i have a new value in req.sessionID, also no cookie will be created with the sessionID.
About this issue
- Original URL
- State: open
- Created 10 years ago
- Reactions: 4
- Comments: 30
If you’re using the window.fetch method to send requests to your server, you have to include 'same-origin credentials in your request. See the example below.
fetch(url, { method: "POST", body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, credentials: "same-origin" })
Watch out cookie property with ‘secure’ value if not in under https protocol req.user will be undefined.
Putting express.session() before passport.session() fixed the issue for me, thanks.
I had this problem. The fix was to add the express-session secret into the cookie parser. problem solved.
So the fix for above would be:
app.use(cookieParser(‘foo’)); app.use(expressSession({ secret : ‘foo’, cookie : { expires: false, domain: config.cookie.domain }, store: redisSessionStore }));
notice the cookie parser now contains the session secret.
It seems to me the real bug here isn’t that
req.user
can be undefined: the real problem is that many different things can all go wrong, and there’s no diagnostic info provided to the user whatsoever to help them figure out what they did wrong (which can be especially confusing because “they”, the server programmer, may not have done anything wrong, as the problem could be completely client-side).It seems like at least the majority of the above cases could be caught. For instance, if passport sees two sessions for identical URLs except one has
www.
and one doesn’t, it seems like it would be trivial for it toconsole.warn("Multiple sessions for the same base URL detected (are you using credentials: 'same-origin'?)")
.I would imagine these warnings would be very easy to implement, but they also sound like they’d be hugely valuable. After just losing half a day to the
www.
one specifically I’d certainly be willing to submit a PR for it, and possibly for others, if desired.I had same issue, both with req.isAuthenticated() and req.user, here is how I resolved
resolved by replacing findOne() with find() in findById() method inside deserialize(), then I could save authenticated req, else it was returning nothing.
resolved by adjusting order, first express-session should be stored then passport should be initialized then next session store in passport.session() and after that we can access req.user, after saving session in passport.session()
Had isses with express-session. I switched to expressjs/cookie-session and seems to be working fine with express@4.42, passport@0.2.0, passport-persona
Thank you @asdkazmi !!!
Adding these below the express session use in app.js did the trick for me here in March 2024 😃
I, too, had this problem, and @SaydChada’s hint got me pointed in the right direction:
Also note that if you do indeed want to request a secure cookie be sent to the browser (s/b typical, IMHO), but you’re using
express-session
and terminating TLS somewhere upstream, this little gem right there in the docs is a good answer:In my case, I’m running in Google App Engine, configured for TLS/SSL only, which terminates TLS upstream.
See also:
https://github.com/expressjs/session#cookiesecure https://expressjs.com/en/guide/behind-proxies.html https://github.com/expressjs/session/blob/master/index.js#L639
Guys, since you are using a custom callback to handle success/failures, it becomes the application’s responsibility to establish a session . So we need to set req.session.user = {…} in the strategies.
I added a new route to keep using “req.user”:
app.use((req, res, next) => {req.user = req.session.user; next()})
The issue for me was that I was not consistent in linking through my site. Make sure you either prefix ’ www.’ everywhere or nowhere, or a new session will be started for the two!