通过json发送passport错误

通过json发送passport错误,json,angularjs,node.js,passport.js,Json,Angularjs,Node.js,Passport.js,我正在用express+passport和angularJS制作一个应用程序;我希望能够通过json发送passport产生的任何错误(如用户名或未提供电子邮件),以便我的angularJS应用程序可以在json响应中接收这些错误。更具体地说,现在我希望对我的signuppost方法有一个输出任何错误的json响应。我试着为自己做这件事,我在网上到处搜索,堆栈溢出,我就是无法解决这个问题 以下是我在express中的用户路由文件: var express = require('express')

我正在用express+passport和angularJS制作一个应用程序;我希望能够通过json发送passport产生的任何错误(如用户名或未提供电子邮件),以便我的angularJS应用程序可以在json响应中接收这些错误。更具体地说,现在我希望对我的signuppost方法有一个输出任何错误的json响应。我试着为自己做这件事,我在网上到处搜索,堆栈溢出,我就是无法解决这个问题

以下是我在express中的用户路由文件:

var express = require('express');
var router = express.Router();
var isAuthenticated = require('../config/isAuthenticated');

module.exports = function(passport){
    router.get('/loggedin', function(req, res){
        res.send(req.isAuthenticated() ? req.user : '0');

    });

    router.post('/signup', passport.authenticate('local-signup', {
        successRedirect : '/',
        failureRedirect : '/signup',
        failureFlash: true
    }));

    router.post('/login', passport.authenticate('local-login'), function(req, res){
        res.send(req.user);
    });


    router.post('/signout', function(req,res){
        req.logout();
        res.json({redirect: '/'});
    });

    router.get('/authtest', isAuthenticated, function(req, res){
        res.render('authtest', {user: req.user});
    });

    return router;
};
这是我的护照注册策略:

passport.use('local-signup', new LocalStrategy({
    usernameField : 'username',
    passwordField : 'password',
    passReqToCallback : true
},
function(req, username, password, done){
    process.nextTick(function(){
        User.findOne({'local.username' : username}, function(err, user){
            if(err) return done(err); 
            if (user) { //username already exists
                return done(null, false, {message: 'Username already exists'});     
            } else if(!req.body.email) { //no email address provided
                return done(null, false, {message: 'You must provide an email address!'});
            } else {
                var newUser = new User();
                newUser.local.username = username;
                newUser.generateHash(password, function(err, hash){
                    if(err) return done(err);
                    newUser.local.password = hash;
                });
                newUser.email = req.body.email;
                newUser.servers = [];
                newUser.save(function(err){
                    if(err) throw err;
                    return done(null, newUser);
                }); 
            };
        });
    });
}
));
我知道现在看看我的代码,看起来我自己根本没有试图解决这个问题,但这只是我最新的工作代码;在过去的几天里,我一直在做这件事


任何帮助都将不胜感激:)

根据passport的当前代码,这可能通过传递自定义回调来实现,以自行处理所有身份验证结果。此回调是在选项之后给出的,或者不是在这些选项之后给出的

passport( "local-signup", { ... }, callbackFn );

此回调用于尝试进行身份验证的所有结果情况。因此,在处理如下错误时调用:

callbackFn( err )
如果(所有配置的)身份验证失败,将使用调用它

callbackFn( null, false, challenge(s), status(es) )
成功对用户进行身份验证后,将按如下方式调用回调:

callbackFn( null, user, infos )
使用策略提供的
infos

现在是最底层:在任何一种情况下
passport.authenticate()
跳过通常的处理,但立即调用提供的回调来处理其余部分。这包括处理调用
passport.authenticate()
时传递的任何选项,如闪烁消息、准备会话和包含已验证用户的请求等

  • 由于给定的选项
    passport.authenticate()
    从未传递到回调中,因此实际上没有明显的理由同时使用这两个选项
  • <> Li >当我遇到了同样的问题(把护照服务与角JS POST请求联系起来)时,我拒绝考虑使用回调一个适当的解决方案。此回调没有文档记录。而且它看起来也不是很有用,因为它没有通过
    req
    res
    next
    来传递回调中的任何实际请求。因此,使用它是毫无意义的,我希望它很快就会消失或者改变它的行为 因此,第二种方法是试图找出AngularJS中存在问题的原因。Passport正在发送纯文本
    未经授权
    ,以响应状态代码
    401
    。AngularJS试图将其解析为JSON并产生语法错误。文本
    Unauthorized
    是通过调用

    res.statusCode = 401;
    res.end(http.STATUS_CODES[res.statusCode]);
    
    因此,一个适当的解决方法可能会试图取代

  • http.STATUS\u code
    中的任一文本,尽管这会对处理进一步的请求产生影响,因此不可取
  • 或者如果
    res.statusCode
    为401,则通过重载方法执行不同的操作
  • 由于影响了当前的任何请求,我只尝试了后者。替换的
    res.end()
    可用于发送所需的任何文本:

    router.post(“/login”,
    功能(req、res、next){
    var _end=res.end;
    res.end=函数(){
    如果(res.statusCode===401){
    返回_end({“status”:“Unauthorized”});
    }
    return _end.apply(这是参数);
    };
    next();
    },
    passport.authenticate('local-login'),
    功能(req、res){
    res.send(请求用户);
    }
    );
    
    或者,替换的方法可能会在内容类型上添加以前缺少的响应头信息,因为这实际上会导致AngularJS在默认情况下将该响应作为JSON处理时出现问题

    router.post(“/login”,
    功能(req、res、next){
    var _end=res.end;
    res.end=函数(){
    如果(res.statusCode===401){
    res.set(“内容类型”、“文本/普通”);
    }
    return _end.apply(这是参数);
    };
    next();
    },
    passport.authenticate('local-login'),
    功能(req、res){
    res.send(请求用户);
    }
    );
    
    最后,这两种方法实际上都只是一种变通方法。我认为passport需要修改这个恼人的限制

    res.statusCode = 401;
    res.end(http.STATUS_CODES[res.statusCode]);