-->

passport's req.isAuthenticated always returnin

2019-01-08 19:57发布

问题:

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:

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.



回答3:

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)


回答4:

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.



回答5:

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


回答6:

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.



回答7:

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

}


回答8:

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.



回答9:

Use Authentication in the below given manner it will work for sure as passport wants express-session for the isAuthenticated to work

//======================================installation of utilities======================================//
var express =      require("express"),
app =              express(),
bodyParser =       require("body-parser"),
mongoose =         require("mongoose"),
Campsite =         require("./models/campsite"),
override =         require("method-override"),
Comments =         require("./models/comments"),
seedDB =           require("./seed"),
User   =           require("./models/user.js"),
passport =         require("passport"),
passportlocal =    require("passport-local"),
passportmongoose = require("passport-local-mongoose")

//======================================uitilities setup ==============================================//

app.use(override("_method"))
app.use(bodyParser.urlencoded({ extended: true }))
app.set("view engine","ejs")
seedDB()

app.use(require("express-session")({
    secret:"random text input",
    resave:false,
    saveUninitialized:false
}))
app.use(passport.initialize())
app.use(passport.session())
passport.use(new passportlocal(User.authenticate()))
passport.serializeUser(User.serializeUser())
passport.deserializeUser(User.deserializeUser())
mongoose.connect("mongodb://localhost/yelpCamp")
app.use(function(req, res, next){
   res.locals.currentUser = req.user;
   next();
});