无法通过Passport.js身份validation时发送JSON响应

对不起,我对node.js非常陌生,所以我还没有能够围绕这个包裹。 我使用Node.js作为iPhone客户端的后端API服务器。 我正在使用Passport.js进行本地策略的身份validation。 相关代码如下:

// This is in user.js, my user model UserSchema.static('authenticate', function(username, password, callback) { this.findOne({ username: username }, function(err, user) { if (err){ console.log('findOne error occurred'); return callback(err); } if (!user){ return callback(null, false); } user.verifyPassword(password, function(err, passwordCorrect){ if (err){ console.log('verifyPassword error occurred'); return callback(err); } if (!passwordCorrect){ console.log('Wrong password'); return callback(err, false); } console.log('User Found, returning user'); return callback(null, user); }); }); }); 

 // This is in app.js app.get('/loginfail', function(req, res){ res.json(403, {message: 'Invalid username/password'}); }); app.post('/login', passport.authenticate('local', { failureRedirect: '/loginfail', failureFlash: false }), function(req, res) { res.redirect('/'); }); 

现在,我已经设法将失败的loginredirect到/ loginfail,在那里我发回一些JSON到iPhone客户端。 但是,这没有足够的粒度。 我希望能够将相应的错误发送回iPhone客户端,例如:“找不到用户”或“密码错误”。 用我现有的代码,我不明白这是如何完成的。

我试图按照passport.js站点上的自定义callback的示例,但由于缺乏对节点的理解,我无法使其工作。 我怎么能修改我的代码,以便能够发送res.json与适当的错误代码/消息?

编辑:我正在尝试这样的事情现在:

 // In app.js app.post('/login', function(req, res, next) { passport.authenticate('local', function(err, user, info) { if (err) { return next(err) } if (!user) { console.log(info); // *** Display message without using flash option // re-render the login form with a message return res.redirect('/login'); } console.log('got user'); return res.json(200, {user_id: user._id}); })(req, res, next); }); // In user.js UserSchema.static('authenticate', function(username, password, callback) { this.findOne({ username: username }, function(err, user) { if (err){ console.log('findOne error occurred'); return callback(err); } if (!user){ return callback(null, false); } user.verifyPassword(password, function(err, passwordCorrect){ if (err){ return callback(err); } if (!passwordCorrect){ return callback(err, false, {message: 'bad password'}); } console.log('User Found, returning user'); return callback(null, user); }); }); }); 

但是,当我尝试console.log(信息)时,它只是说未定义。 我不知道如何得到这个自定义callback工作…任何帮助将不胜感激!

我相信你的“authentication”静态调用(在你的代码中称为“callback”)的callback函数接受你的代码可以提供的第三个参数 – “信息”。 然后,不要传入{failureRedirect:…}对象,而是传入一个带有3个参数的函数 – err,user和info。 您在validation方法中提供的“信息”将传递给此callback。

护照将这种情况称为“自定义callback”。 请参阅这里的文档: http : //passportjs.org/guide/authenticate/

我遇到了Passport和login响应失败的类似问题。 我正在build立一个API,并希望所有的响应作为JSON返回。 护照对身份为401,身体无效的密码作出响应:“未经授权”。 这只是一个正文中的文本string,而不是JSON,所以它打破了我所期望的所有JSON客户端。

事实certificate,有一种方法可以使Passport只是将错误返回给框架,而不是尝试发送响应本身。

答案是在传递给authenticate的选项中设置failWithError : https : //github.com/jaredhanson/passport/issues/126#issuecomment-32333163

来自jaredhanson在这个问题上的评论:

 app.post('/login', passport.authenticate('local', { failWithError: true }), function(req, res, next) { // handle success if (req.xhr) { return res.json({ id: req.user.id }); } return res.redirect('/'); }, function(err, req, res, next) { // handle error if (req.xhr) { return res.json(err); } return res.redirect('/login'); } ); 

这将在Passport调用next(err)后调用error handling程序。 对于我的应用程序,我写了一个通用的error handling程序特定于我的用例只是提供了一个JSON错误:

 // Middleware error handler for json response function handleError(err,req,res,next){ var output = { error: { name: err.name, message: err.message, text: err.toString() } }; var statusCode = err.status || 500; res.status(statusCode).json(output); } 

然后,我用它的所有API路线:

 var api = express.Router(); ... //set up some routes here, attached to api ... // error handling middleware last api.use( [ handleError ] ); 

我没有find文档中的failWithError选项。 在跟踪debugging器中的代码时偶然发现了这个问题。

此外,在我想出来之前,我尝试了@Kevin_Dente答案中提到的“自定义callback”,但它对我没有用。 我不确定这是否适用于旧版本的护照,或者我只是做错了。

有一个自定义callback的官方文档:

 app.get('/login', function(req, res, next) { passport.authenticate('local', function(err, user, info) { if (err) { return next(err); } if (!user) { return res.redirect('/login'); } req.logIn(user, function(err) { if (err) { return next(err); } return res.redirect('/users/' + user.username); }); })(req, res, next); }); 

https://github.com/passport/www.passportjs.org/blob/master/views/docs/authenticate.md