passport.authenticate回调函数未被执行

12

我正在使用Node.js v8.7.0开发后端,身份验证方面我使用了Passport和Local Passport,我之前用过这个并且一切顺利,但现在我不知道问题出在哪里了,以下是我的代码:

我的策略:

var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy
    passport.use('local', new LocalStrategy({
            usernameField: 'email'
        },
        function (email, password, done) {
            User.findOne({
                email: email,
                is_admin: false
            }, function (err, user) {
                if (err) {
                    return done(err)
                }
                // Return if user not found in database
                if (!user) {
                    return done(null, false, {
                        message: 'User not found'
                    })
                }
                // Return if password is wrong
                if (!user.validPassword(password)) {
                    return done(null, false, {
                        message: 'Password is wrong'
                    })
                }
                // If credentials are correct, return the user object
                return done(null, user)
            })
        }
    ))

这里是调用发生的地方:

router.post('/login', (req, res) => {
    try {
        passport.authenticate('local', function (err, user, info) {
            console.log('here xx')

            var token;
            if (err) {
                console.log(err);
                return res.status(401).json(err);
            }
            // If a user is found
            if (user) {
                console.log('here')

                token = user.generateJwt();
                return res.status(200).json({
                    "token": token
                });
            } else {
                // If user is not found
                res.status(401).json(info);
            }
        })

    } catch (reason) {
        res.status(501).json({
            message: reason.message
        })
    }
})

问题在于我没有得到像console.log或错误信息那样的任何消息,它没有执行passport.authenticate的回调函数...顺便说一下,像注册新用户之类的所有事情都很顺利。

2个回答

20

护照应该被用作中间件。在您的路由中像这样使用:

router.post('/login', passport.authenticate('local'), (req, res) => { })

在路由内,您将可以访问req.user

如果您不使用作为中间件,您可以使用一个回调函数。但是您需要传入reqresnext

例如:

passport.authenticate('local', function (err, user, info) {

})(req, res, next)

以下是一个完整的示例,注意这里不使用中间件,因为在这种情况下您正在定义自定义消息,并需要使用回调函数来获取信息。

router.post('/login', (req, res) => {
    passport.authenticate('local', function (err, user, info) {      
        if (err) {
            return res.status(401).json(err);
        }
        if (user) {
            const token = user.generateJwt();
            return res.status(200).json({
                "token": token
            });
        } else {
            res.status(401).json(info);
        }
    })(req, res, next)
})

请问您能否再明确一下,当我将其用作中间件时需要更改什么? - Mohamed Ettayeb
你需要在你的路由中改变你的实现。删除router.post中的所有护照代码,并按照我上面提到的方式包含它。我会附上完整的代码。 - dzm
@ettayebmohamed,我更新了我的答案,使用回调方法会更适合你,因为你正在passport中定义自定义消息,并希望在你的路由中使用它。 - dzm
为什么要调用它两次?将其用作中间件将要求使用序列化和反序列化以及会话...我不想要这些,我只想以简单的方式使其在回调函数内部调用即可让其正常工作 :( - Mohamed Ettayeb
只是一个复制粘贴错误。我将其作为中间件删除了。关键在于,您需要通过在passport.authenticate的末尾传递(req,res,next)来执行该函数。 - dzm
我在passport.authenticate的末尾添加了(req, res),现在一切都正常工作了,但是我回到我的旧代码,发现我没有复制(req, res)。我感到非常难过,谢谢。 - Mohamed Ettayeb

2
当您使用passport.authenticate作为回调函数时,建立会话(通过调用req.login())和发送响应是您的应用程序的责任。
这里是链接到passport.js文档的链接,可能会有所帮助: http://www.passportjs.org/docs/authenticate/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接