[英]Why does Passport retry the authentication when it fails to connect?
我有一个 Node.js 和 Express 应用程序,使用Passport和passport-ldapauth进行LDAP 身份验证。
一切正常……除非它无法连接到 LDAP 服务器(它可能处于离线状态,或者 IP 地址错误等)。 在这种情况下, passport.authenticate
以某种方式执行了两次(我就是不知道为什么),结果,我收到Error: Can't set headers after they are sent
。
这些是我的 server.js 和 routes.js 的相关部分:
// Import modules
var express = require('express');
var session = require('express-session');
var passport = require('passport');
var passportLdap = require('passport-ldapauth');
// Configure Express, session suppport, and Passport
var app = express();
app.use(session({ resave: false, saveUninitialized: false, secret: 'foo' }));
passport.use('ldap', new passportLdap({server: { /* LDAP settings */ }}));
app.use(passport.initialize());
app.use(passport.session());
// Routings
app.get('/login', function(req, res) { res.render('loginForm.ejs'); });
app.post('/login', function(req, res) {
passport.authenticate('ldap', {session: true}, function(err, user, info) {
if (err || !user) {
console.log(err ? 'ERROR' : 'CREDENTIALS');
res.status(403).render('loginForm.ejs', {message: err || 'Wrong credentials!'});
} else {
console.log('SUCCESS');
res.redirect('/home');
}
})(req, res);
});
如果认证成功,控制台只显示SUCCESS
。
如果用户输入了错误的用户名或密码,它会显示CREDENTIALS
,并再次加载登录表单,显示“错误的凭据!” 信息。 控制台上没有出现错误。
但是,如果 LDAP 服务器关闭,我会在控制台上收到ERROR
两次。 (为什么?!)然后很明显,当它使用相同的响应对象进行第二次res.render
时,我收到了Can't set headers after they are sent
错误。 并且由于这是第二次尝试失败,因此用户仍然会使用正确的错误消息(在第一次尝试时呈现)获得表单登录。
如果我将if (err)
块更改为next(err)
而不是res.render()
...我没有遇到标题问题,但仍然存在 LDAP 异常(例如“错误:getaddrinfo ") 在控制台上显示两次,就好像 Passport 在第一次尝试后重试一样。
另外,我注意到 ldapauth 中有一个handleErrorsAsFailures
选项。 如果我启用它,那么它会在控制台上显示两次CREDENTIALS
以解决连接问题,如果我实际上输入了错误的凭据,则只显示一次。
什么可能导致这个问题?
作为(希望是暂时的?)解决方法,我已将代码更改为:
if (err || !user) {
if (!res.headersSent) { // <---------- CHECK TO PREVENT THE ISSUE ---------
console.log(err ? 'ERROR' : 'CREDENTIALS');
res.status(403).render('loginForm.ejs', {message: err || 'Wrong credentials!'});
}
} else // ...
这可以防止第二次渲染尝试,并避免Can't set headers after they are sent
错误。
我仍然不知道是什么导致了这种行为或如何解决它,虽然......
我的解决方法是使用 if-else 语句将路由中的所有代码包装起来:
if(res.headersSent) {
return;
} else {
*//the rest of the code goes here*
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.