我正在尝试让我的护照本地策略发挥作用。
我已经设置了这个中间件:
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
。为什么它不起作用?
我也有类似的问题。可能是由于护照所需的快速会话中间件。按以下顺序使用中间件修复了此问题:(快递 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());
新手
我面临着类似的问题,我的 isAuthenticated(( 函数将返回 false。我浪费了很多时间,希望这个答案能拯救你。
需要注意的一些常见问题,
- 中间件设置顺序(快速会话> pass.initialize> pass.session (。 序列化
- 和反序列化方法需要向用户传递请求。(有关更多信息,我已在此链接上发布了答案。Pass Session (expressjs( 的基础知识 - 为什么我们需要序列化和反序列化?( 如果没有请求的用户,则 isAuthenticated 将返回 false....并重定向到定义的路径......当假....
- 模型中定义的 getUserById 或 findById 函数(user.js(需要定义 User.findById(而不是 User.findOne(函数。(此函数将在每个会话中加载用户的请求(
这也可能是您客户的 POST/GET 调用的问题。我遇到了完全相同的问题,但事实证明我必须给fetch
(这就是我正在使用的(选项credentials:'include'
如下所示:
fetch('/...', {
method: 'POST',
headers: myHeaders,
credentials: 'include',
body: ...
...})
原因是 fetch 不支持传递 cookie,而在这种情况下,这是必需的。
我的问题是我将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
}));
如果您不使用https,请记住将cookie设置为false。
cookie: { secure: false } // Set to false
此外,如果您确实认为自己有https,请记住信任代理
app.set('trust proxy', 1) // trust first proxy
我忘记添加
request.login()
上
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);
}
);
希望这可能会对那些和我一样原因来到这里的其他人有所帮助。
护照上有一个扭结.js没有人真正提到,但我发现了。这就是为什么您可以创建一个帐户或登录,它一开始身份验证正常,但后来您会发现req.user
undefined
或req.isAuthenticated()
在整个应用程序中false
。
身份验证后,护照.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 应用程序都是如此。
我也有同样的问题,在网上找不到任何解决方案,但我想通了。
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}));
快速会话要求和使用应优先于任何其他用途。试试这个,我相信这会起作用,对我有用!!
晚了,但我在FB登录策略中遇到了这个问题。它工作正常,直到突然停止工作,而且在 Safari 中也是如此。我对上述所有解决方案都感到困惑,但似乎没有任何效果。最后,chrome网络控制台给出了一个线索,其中它仍然可以在chrome上运行。警告是这样的:
设置了与http://www.facebook.com/
处的跨站点资源关联的 Cookie,但没有 SameSite
属性。Chrome 的未来版本将仅在设置了 SameSite=None
和 Secure
的情况下提供带有跨站点请求的 cookie
直到那时我才意识到我不应该在快速会话中设置 Samesite:true,因为它不会设置 facebook cookie 进行登录。经过几天的黑客攻击,我通过将同一站点更改为"无"来解决此问题。
希望它可以帮助将来遇到此问题的人。
我遇到了同样的问题,问题是 Cookie 在我使用的浏览器上默认被阻止。为了修复它,我将我的应用程序 URL 添加到允许的边以使用 cookie .
对我来说,我做了所有答案所说的,但它不会登录,至少大多数时候是这样。但是,这很奇怪,因为如果我在Chrome开发人员工具中将网络限制为3G,登录确实有效。我的问题是会话没有保存。我会在登录后拥有用户,但在下一个请求进入后立即丢失它。我的解决方案是使用 req.session.save
回调(如此处建议(和 req.logIn()
回调:
router.post("/login", (req, res, next) => {
passport.authenticate("local", {
failureFlash: true,
//failureRedirect: /login", // these don't work!
//successRedirect: "/home", // because they redict too fast
}, (err, user, info) => {
if (err !== null || user === false) {
req.session.save(() => {
// failureRedirectin the callback here
res.redirect("/login");
});
} else {
req.logIn(user, err => {
// save session before redirecting!
req.session.save(() => {
// successRedirectin the callback here
res.redirect("/home");
});
});
}
})(req, res, next);
});
通过等到保存护照会话后再允许下一个请求通过重定向来修复竞争条件。
不确定这是否仅适用于本地策略。使用快速会话。
我通过修复我的护照来解决这个问题.deserializeUser。我使用的是mongo原生的,由于大多数例子都使用Mongoose,我再次陷入了_id陷阱。
所以请记住在反序列化用户中读取用户时将_id设为 mongo ObjectID
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);
});
});
我的查询找不到用户,因为我没有将 id 设为 ObjectID,并且任何地方都没有指示任何错误。
我也面临着同样的问题,但@PVThomas给了我解决方案,就像答案中一样。我的问题是deserialize()
findById()
方法.我在findById()
中使用了findOne()
,然后我用find()
替换了它,现在req.isAuthenticated()
工作正常。我的应用程序没有保存req.session.passport.user
,它返回未定义然后在find()
替换findOne()
后将用户ID保存在req.session.passport.user
中。
登录正在进行,我也遇到了同样的问题。我犯的错误是在初始化护照之前调用中间件 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);
在我的情况下解决了,我也遇到了同样的问题,但只需通过重新排序代码即可解决,如下所述:
//--------------------------------
以前的代码 :
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())
//--------------------------------
重构代码:(修复了问题(:
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()
})
//--------------------------------
我必须同意@karan525。 但是,我确保在我的应用程序页面上的不同位置测试我的代码部分。 它最终为我工作的地方是开始,但在任何配置文件之后。
// Session
app.use(session({
secret: 'not so secret',
resave: true,
saveUninitialized: true,
}));
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
我相信你的错误来自视图,无论是 ejs、pg 还是反应。 窗体组中没有与传递给 localStrategy 回调函数的参数对应的 name 属性。这就是为我修复它的原因。
我面临着类似的问题。我通过更改函数调用的顺序来修复它。
// Call session middleware first
expressApp.use(session(....blah))
// Then initialize passport
expressApp.use(passport.initialize());
expressApp.use(passport.session());
嘿伙计们,我想在这里分享我的错误。
app.use(session({
secret: process.env.SECRET,
resave: false,
saveUninitialized: true,
cookie: { secure: true }
})
如果使用此代码,请确保按如下方式更改代码,
cookie:{ secure :false}
app.use(
session({
secret: 'Our little secret.',
resave: false,
saveUninitialized: true,
cookie: { secure: true } << it was extra for me
})
);
cookie 中的安全密钥设置为 false
如果您像这样包装路由:
module.exports = function(){
router.get('/',(req,res)=>{
res.send('stuff');
}
}
您必须将"应用程序和护照"传递到您的路线,如下所示:
module.exports = function(app,passport){
//routes n stuff
}