可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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,
- Middleware setup order (express-session > pass.initialize > pass.session )(and while you do that CHECK YOUR SYNTAX).
- 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.
- 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();
});