Паспорт req.isAuthenticated всегда возвращает false, даже когда я сделал hardcode (null, true)
Я пытаюсь использовать свою локальную стратегию Passport.
У меня установлено это промежуточное программное обеспечение:
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"});
}));
но затем здесь
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('/');
}
он всегда терпит неудачу и перенаправляется на главную страницу.
Я не могу понять, почему это происходит? Почему он не аутентифицируется?
В моей консоли я вижу, что Password Correct
печатает.
Почему он не работает?
Ответы
Ответ 1
У меня была аналогичная проблема. Возможно, это связано с промежуточным программным обеспечением экспресс-сессии, необходимым для паспорта. Исправлено с помощью промежуточных устройств в следующем порядке: (Экспресс 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
ДЛЯ НОВОЙ
Я столкнулся с аналогичной проблемой, где моя функция isAuthenticated() вернула false.I потеряла много времени, надеюсь, что этот ответ сохранит ваши.
Некоторые общие проблемы, о которых нужно помнить,
- Порядок настройки промежуточного ПО (express-session > pass.initialize > pass.session) (и пока вы это делаете, ПРОВЕРИТЕ СВОЙ СИНТАКС).
- Методы Serialize и Deserialize должны передавать пользователя по запросу. (Для получения дополнительной информации я отправил ответ по этой ссылке.. Основы сеанса паспорта (expressjs) - почему нам нужно сериализовать и десериализовать?), если нет пользователя по запросу, то isAuthenticated вернет false.... и перенаправит на PATH, определенный...... когда false.... И... ОДИН РАЗ СНОВА..... ПРОВЕРЬТЕ СВОЙ СИНТАКС.
- Функция getUserById или findById, определенная в модели (user.js), должна иметь User.findById(а не User.findOne Again CHECK YOUR.. WAIT FOR IT..SYNTAX) (эта функция будет загружать пользователя по запросу в каждом сеансе).
Ответ 3
Это также может быть проблемой при звонках клиента POST/GET. У меня была такая же проблема, но оказалось, что я должен был дать fetch
(это то, что я использовал) вариант credentials:'include'
следующим образом:
fetch('/...', {
method: 'POST',
headers: myHeaders,
credentials: 'include',
body: ...
...})
Причина в том, что выборка не поддерживает передачу файлов cookie, что необходимо в этом случае.
Ответ 4
Моя проблема заключалась в том, что я установил для cookie.secure значение true, даже если данные не превышали 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
}));
Не забудьте установить куки на false, если вы не используете https
cookie: { secure: false } // Set to false
Также, если вы уверены, что у вас есть https, не забудьте доверять прокси
app.set('trust proxy', 1) // trust first proxy
Ответ 5
У меня была такая же проблема, забыв добавить
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);
}
);
Надеюсь, это может помочь другим, которые оказались здесь той же причиной, что и я.
Ответ 6
В passport.js есть излом, который никто не упоминает, но я узнал. Вот почему вы можете создать учетную запись или войти в систему, и вначале она аутентифицируется, но позже вы обнаружите, что req.user
- это undefined
или req.isAuthenticated()
- это false
во всем приложении.
После аутентификации passport.js требует от вас перенаправления/перенаправления. Таким образом, паспорт инициализирует фактический сеанс.
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")
}
})
}
Если вы не выполните перенаправление после аутентификации, он даже не начнет сеанс, поскольку req.user
и req.isAuthenticated()
будут ложными.
Мое приложение является приложением React и Node, но это верно как для приложений Node, так и для приложений React/Node.
Ответ 7
Я исправил эту проблему, установив свой паспорт .deserializeUser. Я использую mongo native, и поскольку большинство примеров используют Mongoose, я снова попал в ловушку _id.
Поэтому не забудьте сделать _id Mongo ObjectID при чтении пользователя в 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);
});
});
Мой запрос не нашел пользователя, так как я не делал идентификатор ObjectID, и никаких ошибок не было указано нигде.
Ответ 8
Если вы оберните ваши маршруты так:
module.exports = function(){
router.get('/',(req,res)=>{
res.send('stuff');
}
}
Вы должны передать "приложение и паспорт" на ваши маршруты следующим образом:
module.exports = function(app,passport){
//routes n stuff
}
Ответ 9
Я также столкнулся с той же проблемой, но @PVThomas дает мне решение, как здесь, в Ответах. Моя проблема была с findById()
в deserialize()
. Я использовал findOne()
в findById()
а затем заменил его на find()
и теперь req.isAuthenticated()
работает нормально. Мое приложение не req.session.passport.user
, оно возвращало undefined и затем после замены findOne()
на find()
req.session.passport.user
идентификатор пользователя в req.session.passport.user
.
Ответ 10
Я также столкнулся с той же проблемой, хотя вход в систему происходил. Я сделал ошибку, вызвав промежуточное программное обеспечение isLoggedIn перед инициализацией паспорта. Поэтому последовательность, в которой вы пишете код, очень важна. Пожалуйста, следите за тем, чтобы последовательность была написана в правильном порядке. Я написал в следующей последовательности
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);
Ответ 11
У меня тоже была такая же проблема, я не мог найти какое-либо решение в Интернете, но я понял это.
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}));
требование и использование экспресс-сессии должны быть перед любым другим использованием. Попробуйте это, я уверен, что это будет работать, работал для меня!