passport's req.isAuthenticated always returning false, even when I hardcode done(null, true)

node.jsExpresspassport.jsPassport Local

node.js Problem Overview


I'm trying to get my Passport local strategy working.

I've got this middleware set up:

passport.use(new LocalStrategy(function(username, password, done) {
    //return done(null, user);
    if (username=='ben' && password=='benny'){
        console.log("Password correct");
        return done(null, true);
    }
    else
        return done(null, false, {message: "Incorrect Login"});
}));

but then in here

app.use('/admin', adminIsLoggedIn, admin);

function adminIsLoggedIn(req, res, next) {

    // if user is authenticated in the session, carry on 
    if (req.isAuthenticated())
        return next();

    // if they aren't redirect them to the home page
    res.redirect('/');
}

it always fails and redirects to the home page.

I can't figure out why this is happening? Why won't it authenticate?

In my console I can see that's Password Correct is printing. Why won't it work?

node.js Solutions


Solution 1 - node.js

I had a similar issue. Could be due to the express-session middleware needed for passport. Fixed it by using middlewares in the following order: (Express 4)

var session = require('express-session');

// required for passport session
app.use(session({
  secret: 'secrettexthere',
  saveUninitialized: true,
  resave: true,
  // using store session on MongoDB using express-session + connect
  store: new MongoStore({
    url: config.urlMongo,
    collection: 'sessions'
  })
}));

// Init passport authentication 
app.use(passport.initialize());
// persistent login sessions 
app.use(passport.session());

Solution 2 - node.js

FOR NEWBIES

I was facing a similar problem, where my isAuthenticated() function would return false.I lost a lot of time, hope this answer saves yours.

Some Common problems to watch out for,

  1. Middleware setup order (express-session > pass.initialize > pass.session ).
  2. Serialize and Deserialize methods needs to pass user on the request.(For more info I've posted an answer on this link.. https://stackoverflow.com/q/45381931/8229646 ) if there's no user on request then isAuthenticated would return false.... and redirect to the PATH defined ......when false....
  3. The getUserById or findById function defined in the model(user.js) needs to have a User.findById (and not User.findOne) function defined.(this function would load user on the request in every session)

Solution 3 - node.js

My problem was that i set cookie.secure to true even if data was not over https.

app.use(require('express-session')({
    secret: process.env.sessionSecret,
    cookie: {
        maxAge: 1000 * 60 * 60 * 24 * 7 // 1 week
    },
    store: store,
    resave: false,
    saveUninitialized: false,
    cookie: { secure: false } // Remember to set this
}));

Remember to set cookies to false if you're not using https

cookie: { secure: false } // Set to false

Also if you do believe you have https remember to trust the proxy

app.set('trust proxy', 1) // trust first proxy

Solution 4 - node.js

This could also be an issue with your client's POST/GET calls. I had this exact same issue but it turned out that I had to give fetch (which is what I was using) the option credentials:'include' like so:

fetch('/...', {
  method: 'POST',
  headers: myHeaders,
  credentials: 'include',
  body: ...
  ...})

The reason is because fetch doesn't support passing down cookies, which is necessary in this case.

Solution 5 - node.js

I had the same issue by forgetting to add

request.login()

on

app.post('/login', 
	function(request, response, next) {
		console.log(request.session)
		passport.authenticate('login', 
		function(err, user, info) {
			if(!user){ response.send(info.message);}
			else{

				request.login(user, function(error) {
					if (error) return next(error);
					console.log("Request Login supossedly successful.");
					return response.send('Login successful');
				});
				//response.send('Login successful');
			}

		})(request, response, next);
	}
);

Hopefully that might help for others that ended up here same reason as I did.

Solution 6 - node.js

I also had the same problem, could not find any solution on the web but i figured it out.

app.use(require("express-session")({
secret: "This is the secret line",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({extended: true}));

express-session requirement and use should be before any other use. Try this i am sure this would work, worked for me!!

Solution 7 - node.js

There's a kink in passport.js that nobody really mentions but I found out. This is why you can create an account or sign in and it authenticates fine at first but later on you find out req.user is undefined or req.isAuthenticated() is false throughout the app.

After authenticating, passport.js requires you to reroute/redirect. That's how passport initializes the actual session.

  signIn(req, res, next) {
    passport.authenticate("local")(req, res, function() {
      if (!req.user) {
        console.log("User not found!");
      } else {
        res.redirect("/")
        console.log("signed in")
      }
    })
  }

If you don't reroute after authenticating, it won't even start your session as a req.user and req.isAuthenticated() will be false.

My app is a React and Node app but this is true for both Node apps and React/Node apps.

Solution 8 - node.js

I know its late, but I face this issue with FB login strategy. It was working fine, until suddenly it stopped working and that too just in Safari. I broke my head around all of the above solutions and nothing seemed to work. Finally chrome web console gave away a clue, wherein it still worked on chrome, then. The warning was this:

A cookie associated with a cross-site resource at http://www.facebook.com/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure.

Only then i realized that i shouldn't set Samesite: true in the express session as it will not set the facebook cookie for login. After days of hacking, I fixed this issue by changing the samesite to "none".

Hope it helps someone, who encounters this issue in the future.

Solution 9 - node.js

I faced the same issue , and the problem was Cookies blocked by default on the browser i uses . To fix it i add my app URL to the allowed sides for use cookies .

Solution 10 - node.js

I fixed this issue by fixing my passport.deserializeUser. I'm using mongo native and since most of the examples use Mongoose i fell in to the _id trap once again.

So remember to make the _id a mongo ObjectID when reading the user in deserializeUser

passport.deserializeUser(function(user, done) {
    const collection = db.get().collection('users')
    const userId = new mongo.ObjectID(user);
    collection.findOne({_id : userId}, function(err, user) {
        if (err) done(err, null);
        done(null, user);
    });
});

My query was not finding the user since I did not make the id an ObjectID, and there was no errors indicated anywhere.

Solution 11 - node.js

I also was facing same problem, but @PVThomas gives me solution, as in here in Answers. My problem was with findById() method in deserialize(). I was using findOne() in findById() and then I replaced it with find() and now req.isAuthenticated() is working fine. My app wasn't saving req.session.passport.user, It was returning undefined and then after replacement of findOne() with find() it's saving user id in req.session.passport.user.

Solution 12 - node.js

I also faced the same problem even though logging in was happening. The mistake I did was calling the middleware isLoggedIn before initializing the passport. So the sequence in which you write the code is quite important.Please see to it that the sequence is written in the right order. I had written in the following sequence

app.use(require('express-session')({
	secret:'short' ,
	resave:false,
  saveUninitialized:false,
  cookie:{secure:false}
}))
app.use(passport.initialize())
app.use(passport.session())
passport.use(new localstrategy(function(username, password, done) {
    User.findOne({ username: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) { return done(null, false); }
      if (user.password!=password) { return done(null, false); }
      return done(null, user);
    });
  }
))
passport.serializeUser(User.serializeUser())
passport.deserializeUser(User.deserializeUser())
app.use(isLoggedIn); 

Solution 13 - node.js

app.use(
    session({
        secret: 'Our little secret.',
        resave: false,
        saveUninitialized: true,
        cookie: { secure: true } << it was extra for me
    })
);

Solution 14 - node.js

Resolved in my case, I also faced the same problem, but resolved just by reordering the code as mentioned below:

//--------------------------------

previous code :

app.use(flash())
app.use(session({
    secret: 'somesecret',
    resave: false,
    saveUninitialized: false
}))
// using the custom middleware for storing variable in response
app.use((req, res, next) => {
    res.locals.isAuthenticated = req.isAuthenticated()
    next()
})
app.use(passport.initialize())
app.use(passport.session())

//--------------------------------

Refactored code : (which fixed the problem):

app.use(flash())
app.use(session({
    secret: 'somesecret',
    resave: false,
    saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())

// using the custom middleware for storing variable in response
app.use((req, res, next) => {
    res.locals.isAuthenticated = req.isAuthenticated()
    next()
})

//--------------------------------

Solution 15 - node.js

I have to agree with @karan525. However, I made sure to test the portion of my code at different locations on my app page. Where it finally worked for me was towards the start but after any configuration files.

// Session 
app.use(session({
secret: 'not so secret',
resave: true,
saveUninitialized: true,
}));

// Passport middleware
app.use(passport.initialize());
app.use(passport.session());

Solution 16 - node.js

I believe your error is from the view, either ejs, pug or react. there is no name property in your form group corresponding to the arguments passed to the localstrategy callback function. This is what fixed it for me.

Solution 17 - node.js

I was facing the similar problem. I fixed it by changing the sequence of function calls.

// Call session middleware first
expressApp.use(session(....blah))

// Then initialize passport
expressApp.use(passport.initialize());
expressApp.use(passport.session());

Solution 18 - node.js

Hey guys I would like to share my mistake here.

app.use(session({
    secret: process.env.SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true }    
  })

If you use this code make sure to change the code as follows,

cookie:{ secure :false}

Solution 19 - node.js

Set the secure key in the cookie to false

Solution 20 - node.js

If you wrap your routes like so:

module.exports = function(){

router.get('/',(req,res)=>{
 res.send('stuff');
  }

}

You have to pass "app and passport" to your routes like so:

module.exports = function(app,passport){

//routes n stuff

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCodyBugsteinView Question on Stackoverflow
Solution 1 - node.jsNitinView Answer on Stackoverflow
Solution 2 - node.jsPRAKASH THOMAS VARGHESEView Answer on Stackoverflow
Solution 3 - node.jsThomas LindauerView Answer on Stackoverflow
Solution 4 - node.jsAlex HView Answer on Stackoverflow
Solution 5 - node.jsozgeneralView Answer on Stackoverflow
Solution 6 - node.jskaran525View Answer on Stackoverflow
Solution 7 - node.jsuser11269493View Answer on Stackoverflow
Solution 8 - node.jsBadriNarayanan SridharanView Answer on Stackoverflow
Solution 9 - node.jsAl-Mustafa AzhariView Answer on Stackoverflow
Solution 10 - node.jsMikkoView Answer on Stackoverflow
Solution 11 - node.jsSyed Muhammad AsadView Answer on Stackoverflow
Solution 12 - node.jsSuyash SreekumarView Answer on Stackoverflow
Solution 13 - node.jsGio RomanadzeView Answer on Stackoverflow
Solution 14 - node.jsMr. ShanView Answer on Stackoverflow
Solution 15 - node.jsAnEmptyBoxView Answer on Stackoverflow
Solution 16 - node.jsProspeeView Answer on Stackoverflow
Solution 17 - node.jsDinesh VermaView Answer on Stackoverflow
Solution 18 - node.jsSparkView Answer on Stackoverflow
Solution 19 - node.jsLeksykingView Answer on Stackoverflow
Solution 20 - node.jsmetal_jacke1View Answer on Stackoverflow