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

梦想与她 提交于 2019-11-26 22:21:58

问题


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?


回答1:


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



回答2:


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 )(and while you do that CHECK YOUR SYNTAX).
  2. Serialize and Deserialize methods needs to pass user on the request.(For more info I've posted an answer on this link.. Basics of Passport Session (expressjs)-why do we need to serialize and deserialize? ) if there's no user on request then isAuthenticated would return false.... and redirect to the PATH defined ......when false....AND... ONCE AGAIN.....CHECK YOUR SYNTAX.
  3. The getUserById or findById function defined in the model(user.js) needs to have a User.findById (and not User.findOne Again CHECK YOUR.. WAIT FOR IT..SYNTAX) function defined.(this function would load user on the request in every session)



回答3:


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.




回答4:


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



回答5:


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.




回答6:


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!!




回答7:


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.




回答8:


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.




回答9:


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

}



回答10:


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.




回答11:


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


来源:https://stackoverflow.com/questions/29111571/passports-req-isauthenticated-always-returning-false-even-when-i-hardcode-done

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!