Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

req.user is undefined, passport not working with Express 4.0 #244

Open
tschiela opened this issue May 9, 2014 · 30 comments
Open

req.user is undefined, passport not working with Express 4.0 #244

tschiela opened this issue May 9, 2014 · 30 comments

Comments

@tschiela
Copy link

tschiela commented May 9, 2014

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.

@mgutz
Copy link

mgutz commented Jun 12, 2014

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

@naxmefy
Copy link

naxmefy commented Jun 13, 2014

can u post the post function where u authenticate the user?

Had same issue with custom callback authentication - but not with flash Authentication (flash not works but session will be set with user infos).

@vonbirdie
Copy link

There is another issue for this in #222...

@crsrusl
Copy link

crsrusl commented Jun 25, 2014

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.

@trshafer
Copy link

I had this issue. The problem was really that I was trying to access a redis db number I didn't have access to. When I removed the db from my redis config, it worked again.

@bassie1995
Copy link

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!

@bicarlsen
Copy link

I had the same issue. Turns out it was a dependency issue with express-sesssion. From the Passport site:

If [sessions are] enabled, be sure to use express.session() before passport.session() to ensure that the login session is restored in the correct order.

@qdouble
Copy link

qdouble commented Oct 29, 2015

Putting express.session() before passport.session() fixed the issue for me, thanks.

@Arcrammer
Copy link

+1

1 similar comment
@shivasurya
Copy link

+1

@valerieernst
Copy link

valerieernst commented Jan 23, 2017

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" })

@SaydChada
Copy link

Watch out cookie property with 'secure' value if not in under https protocol req.user will be undefined.

@zelenkoff
Copy link

Big thanks @valerieernst !

@justin-haworth
Copy link

@valerieernst HUGE THANK YOU!!!! A ton of Googling and your advice got my stuff working.

@MichaelWStuart
Copy link

@valerieernst thanks!

@nagmak
Copy link

nagmak commented Apr 10, 2017

omg @SaydChada thank you so much! I've been stuck for ages, and it was this one line of code driving me insane.

@Arcrammer
Copy link

Arcrammer commented Apr 16, 2017

I did what @mgutz said — Uninstall express-session and use cookie-session instead. It's working for me now so thank you, @mgutz! I believe I had both express-sessionand cookie-session installed so maybe they were conflicting with each other. I'll stick to cookie-session since I know that's working.

@cideM
Copy link

cideM commented Apr 18, 2017

@valerieernst You are a saint, thank you so much for this small yet absolutely essential piece of information. Here is Github Gold. No wait, but I'll subscribe to your channel. Or follow your feed. +1 your post, whatever, have all the upvotes!

@andreabat
Copy link

In case someone is having this problem due to nginx as ssl proxy to express.
Found a working solution here:
https://gist.github.com/nikmartin/5902176

@webarthur
Copy link

webarthur commented Nov 25, 2017

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()})

@nikkwong
Copy link

There's a suttle bug with express-session that can bite you, link but cookie-session is basically a drop in replacement that has worked perfectly for me.

@machineghost
Copy link

machineghost commented Feb 13, 2018

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 to console.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.

@morajabi
Copy link

@machineghost You can always do a PR yourself! 😉

@machineghost
Copy link

As I said, I'd be happy to, but I never waste time on PRs that maintainers don't want. Until a project maintainer indicates that such a warning would actually be desired I'll hold off.

@asdkazmi
Copy link

I had same issue, both with req.isAuthenticated() and req.user, here is how I resolved

  • req.isAuthenticated()

resolved by replacing findOne() with find() in findById() method inside deserialize(), then I could save authenticated req, else it was returning nothing.

  • req.user

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()

app.use(session(...))
app.use(passport.initialize());
app.use(passport.session());
// Now we can access req.user so after we will call req.user, if we write it above these, it will always return underfined
app.use(function(req, res, next){
  res.locals.user = req.user || null
  next();
})

@EmmyMay
Copy link

EmmyMay commented Jul 12, 2019

I have a problem if anybody here could help, please. In my case, cookies are being saved to the browser but they are not being used. I know this because my app doesn't go to a state of logged-in. I just keep getting redirected to google's site every time. I am using passport's google strategy.

@Rishabh570
Copy link

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.

@crsrusl This worked for me. Before this, I had to manually set req.user = user in my JWT verify callback but after passing the same secret to both cookie-parser and cookie-session, req.user got set automatically. I wonder why this is the case...I would appreciate any explanation regarding this.

@TimJohns
Copy link

TimJohns commented Sep 3, 2020

I, too, had this problem, and @SaydChada's hint got me pointed in the right direction:

Watch out cookie property with 'secure' value if not in under https protocol req.user will be undefined.

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:

If you have your node.js behind a proxy and are using secure: true, you need to set "trust proxy" in express

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

@Wandersonelias
Copy link

in my case, i use this config, resolveded the problem
app.use(session({
secret: "123",
resave: true,
saveUninitialized: true,
cookie: {maxAge: 60 * 60 * 24 * 1000}
}));

@locohost
Copy link

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

Thank you @asdkazmi !!!

Adding these below the express session use in app.js did the trick for me here in March 2024 :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests