Passport JS自定义回调调用3次
我正在构建一个带有护照js的快速js api,并且为了能够返回格式为json的自定义错误消息,我使用的是custom callbacks。Passport JS自定义回调调用3次
当我提供未知的电子邮件时,我写的自定义回调被称为3次,导致Unhandled rejection Error: Can't set headers after they are sent.
。这是有道理的。
任何帮助表示赞赏。
这是我实现:
策略:
const localLoginStrategy = new LocalStrategy({
usernameField: "emailAddress"
}, (emailAddress, password, done) => {
// Called once
User.findOne({
where: { emailAddress }
}).then((existingUser) => {
// Called once
if (!existingUser) { return done(null, false, { message: "Invalid email/password combination", status: 401 }); }
return existingUser.comparePassword(password);
}).then((userData) => {
return done(null, userData);
}).catch((err) => {
return done(null, false, { message: "Invalid email/password combination", status: 401 });
});
});
passport.use(localLoginStrategy);
快递中间件使用自定义回调验证:
const requireUsernamePassword = (req, res, next) => {
if(!req.body.emailAddress || !req.body.password) {
return res.status(400).json({ message: "No emailAddress and/or password provided" });
}
// Called once
passport.authenticate("local", { session: false }, (err, user, info) => {
// Called three times!
console.log("authenticate callback")
if (!user || err) {
return res
.status(info.status || 400)
.json({ message: info.message || "Authentication error" });
}
req.user = user;
return next();
})(req, res, next);
};
您的done
函数多次调用。
我相信当你在then
方法调用return done(...)
,未来then
会再打电话done
。
所以这就是为什么你的callback
功能从requireUsernamePassword
被更多地按时调用。
希望它有帮助。
我一直在努力奋斗,虽然我在你回答的时候已经明白了,但这是正确的答案。 – Alexander
要检查您的强制请求主体字段创建一个通用中间件,将检查必填字段并返回适当的返回码。就像下面一样。
module.exports = function checkParams(params) {
params = params || [];
return function(req, res, next) {
var valid = true;
if(Array.isArray(params)) {
params.forEach(function(_param) {
valid = valid && !!req.body[_param];
});
}
if (valid) { next() } else {return res.status(400).end();} //this is for missing required parameters
};
};
现在让我们说,例如,你有两个API。登录和CreateUser。 API应该途径看起来像下面
app.post('/Login', checkParams(['emailAddress', 'password']), passport.authenticate('local', { failureRedirect: '/login' }), actualLoginMethod);
app.post('/CreateUser', checkParams(['userName', 'Phone']), passport.authenticate('local', { failureRedirect: '/login' }), actualCreateUserMethod);
如果这些参数(在/登录用户名和电话/ CREATEUSER + EMAILADDRESS和密码)的缺失则它会返回400种状态,并从该点停止执行,你可能根据需要更改checkParams的逻辑。
如果需要的参数可用,那么它将检查JWT本地策略。一旦请求通过两个检查点,它就会调用实际的方法。
希望这可能会帮助你。
我喜欢你的想法,但它不是我遇到的问题。不过我会执行check params函数。 – Alexander
什么叫您的requireUsernamePassword中间件?多个呼叫是否可以从呼叫堆栈的前面来?你可以尝试添加一个令人失望的User.findOne(....)'我怀疑它是来自那个,但它可以伤害,并且通常(并不总是)很好的做法来返回承诺。您是否记录了每个3次调用的err/user/info的值? – Boris