ERR_HTTP_HEADERS_SENT: 发送给客户端 Passport 后无法设置 headers
ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client Passport
这个问题以前有人问过,但无法用前面的清单解决任何问题。
我正在尝试使用 passport-cas 进行身份验证,但我 运行 遇到了一个我真的不知道如何解决的错误。
我认为问题在于底部代码:
user.save((err) => {
if (err) { return done(err); }
return done(null, user);
});
尤其是 done(null, user) 会在用户第一次尝试注册时导致错误。
问题:
如果用户点击登录按钮两次,则完美登录。这样做的原因是因为它第一次抛出 ERR_HTTP_HEADERS_SENT 错误,然后重定向到主页。第二次,如前所述,完美运行,因为用户已经在数据库中,不需要创建。
任何帮助都会很棒,我的代码如下:
passport.js:
passport.use(new(require('passport-cas').Strategy)({
ssoBaseURL: 'https://domain.edu/cas',
serverBaseURL: 'http://localhost:8080'
}, function(netid, done) {
User.findOne({
netid: netid
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
const user = new User({
netid: netid
});
user.save((err) => {
if (err) { return done(err); }
return done(null, user);
});
}
return done(null, user);
});
}));
user.js:
exports.casLogin = function(req, res, next) {
passport.authenticate('cas', function(err, user) {
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/');
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.redirect('/');
});
})(req, res, next);
};
app.js:
const userController = require('./controllers/user');
app.get('/cas', userController.casLogin);
您在此代码中两次调用 done()
回调:
passport.use(new(require('passport-cas').Strategy)({
ssoBaseURL: 'https://domain.edu/cas',
serverBaseURL: 'http://localhost:8080'
}, function(netid, done) {
User.findOne({
netid: netid
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
const user = new User({
netid: netid
});
user.save((err) => {
if (err) { return done(err); }
return done(null, user); // calling it again here
});
}
return done(null, user); // calling it first here
});
}));
问题是您传递给 user.save()
的回调是异步调用的,其中的 return
没有来自父函数的 return。因此,继续执行父函数,并在您不希望它被调用时调用 return done(null, user)
。
您可以通过添加另一个 return
.
来修复它
passport.use(new(require('passport-cas').Strategy)({
ssoBaseURL: 'https://domain.edu/cas',
serverBaseURL: 'http://localhost:8080'
}, function(netid, done) {
User.findOne({
netid: netid
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
const user = new User({
netid: netid
});
user.save((err) => {
if (err) { return done(err); }
return done(null, user);
});
return; // <=== add this return
}
return done(null, user);
});
}));
您也可以将 if (!user)
变成 if/else
而不是添加上面的 return
.
这个问题以前有人问过,但无法用前面的清单解决任何问题。
我正在尝试使用 passport-cas 进行身份验证,但我 运行 遇到了一个我真的不知道如何解决的错误。
我认为问题在于底部代码:
user.save((err) => {
if (err) { return done(err); }
return done(null, user);
});
尤其是 done(null, user) 会在用户第一次尝试注册时导致错误。
问题:
如果用户点击登录按钮两次,则完美登录。这样做的原因是因为它第一次抛出 ERR_HTTP_HEADERS_SENT 错误,然后重定向到主页。第二次,如前所述,完美运行,因为用户已经在数据库中,不需要创建。
任何帮助都会很棒,我的代码如下:
passport.js:
passport.use(new(require('passport-cas').Strategy)({
ssoBaseURL: 'https://domain.edu/cas',
serverBaseURL: 'http://localhost:8080'
}, function(netid, done) {
User.findOne({
netid: netid
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
const user = new User({
netid: netid
});
user.save((err) => {
if (err) { return done(err); }
return done(null, user);
});
}
return done(null, user);
});
}));
user.js:
exports.casLogin = function(req, res, next) {
passport.authenticate('cas', function(err, user) {
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/');
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.redirect('/');
});
})(req, res, next);
};
app.js:
const userController = require('./controllers/user');
app.get('/cas', userController.casLogin);
您在此代码中两次调用 done()
回调:
passport.use(new(require('passport-cas').Strategy)({
ssoBaseURL: 'https://domain.edu/cas',
serverBaseURL: 'http://localhost:8080'
}, function(netid, done) {
User.findOne({
netid: netid
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
const user = new User({
netid: netid
});
user.save((err) => {
if (err) { return done(err); }
return done(null, user); // calling it again here
});
}
return done(null, user); // calling it first here
});
}));
问题是您传递给 user.save()
的回调是异步调用的,其中的 return
没有来自父函数的 return。因此,继续执行父函数,并在您不希望它被调用时调用 return done(null, user)
。
您可以通过添加另一个 return
.
passport.use(new(require('passport-cas').Strategy)({
ssoBaseURL: 'https://domain.edu/cas',
serverBaseURL: 'http://localhost:8080'
}, function(netid, done) {
User.findOne({
netid: netid
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
const user = new User({
netid: netid
});
user.save((err) => {
if (err) { return done(err); }
return done(null, user);
});
return; // <=== add this return
}
return done(null, user);
});
}));
您也可以将 if (!user)
变成 if/else
而不是添加上面的 return
.