NodeJS-调用deserializeUser之后在身份验证期间挂起的应用程序(passport.js)

时间:2018-08-13 23:01:03

标签: node.js authentication serialization passport.js hang

我遇到的问题是,提交登录表单时,应用程序挂起并且没有被重定向。

我已经尝试调试该问题,但是我不知道发生了什么。

到目前为止,我发现(在登录提交时)以下内容称为:

登录POST:

<script id="react" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.js"></script>
<script id="react-dom" src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.js"></script>
<div id="container"></div>

调用了中间件,但是重定向从未发生。

使用(本地护照)LocalStrategy进行身份验证:

router.post('/login', passport.authenticate('local-login', {
    successRedirect : '/', // redirect to the secure profile section
    failureRedirect : '/login', // redirect back to the signup page if there is an error
    failureFlash : true // allow flash messages
}) );

Debug显示此操作成功执行。

SerializeUser:

passport.use(
    'local-login',
    new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true // allows us to pass back the entire request to the callback
    },
    function(req, email, password, done) { // callback with email and password from our form
        connection.query("SELECT * FROM users WHERE email=?",[email], function(err, rows){
            if (err)
                return done(err);
            if (!rows.length) {
                return done(null, false, req.flash('login', 'Oops! Wrong email or password')); // req.flash is the way to set flashdata using connect-flash
            }

            // if the user is found but the password is wrong
            if (sha1(password) != rows[0].password) {
                return done(null, false, req.flash('login', 'Oops! Wrong email or password')); 
            }

            // all is well, return successful user
            return done(null, rows[0]);
        });
    })
);

passport.serializeUser收到预期的用户对象。

DeserializeUser:

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

在这里,我不确定会发生什么。应用程序挂起。调试时,我无法越过以下行:

passport.deserializeUser(function(id, done) {
    connection.query("SELECT * FROM users WHERE id=? ",[id], function(err, rows){
        done(err, rows[0]);
    });
});

我一直按'n'或'c',但是什么也没发生。

我可以就我所缺少的内容获得一些建议吗?

还可以有人帮助我更好地了解这些身份验证方法中完成的功能吗?

更新:

用于检查用户是否已登录的功能:

break in net.js:587
 585   // procedure. No need to wait for all the data to be consumed.
 586   self.emit('_socketEnd');
>587 }
 588 
 589 
debug> n
debug> n

1 个答案:

答案 0 :(得分:0)

您需要基于不成功的身份验证将控制权传递到下一条可能的路由,并且您需要使用next()进行控制。所以试试这个

router.post('/login', passport.authenticate('local-login', {
    successRedirect : '/', // redirect to the secure profile section
    failureRedirect : '/login', // redirect back to the signup page if there is an error
    failureFlash : true // allow flash messages
})(req, res, next) ); 

要了解done(),请参考此答案https://stackoverflow.com/a/32154771/7096322

router.post('/login', function (req, res, next) {
        passport.authenticate('local', function(err, user, info) {
            if(err)
                res.status(500).json({status: 'error', message: 'Something went wrong'});
            if(!user) {
                res.status(401).json(info);
            }
            else {
                req.logIn(user, function (err) {
                    if(err)
                        res.status(500).json({status: 'error', message: 'Something went wrong'});
                    else {
                        req.session.user = user;
                        req.session.save(function (err) {
                            if (err) {
                                console.log(err);
                            } else {
                                res.status(200).json({status: 'success', message: 'Login successful'});
                            }
                        });
                    }
                })
            }
        })(req, res, next);
    }
);


passport.use(new LocalStrategy({
        passReqToCallback: true
    },
    function(req, username, password, done) {
        User.forge({ username: username.trim() })
            .fetch()
            .then(function(user) {
                if(!user) {
                    done(null, false, {status: 'error', message: 'Invalid username'});
                }
                else {
                    bcrypt.compare(password, user.get('password'), function (err, res) {
                        if(res === true) {
                            done(null, user);
                        }
                        else {
                            done(null, false, {status: 'error', message: 'Invalid password'});
                        }
                    })
                }
            })
            .catch(function(err) {
                console.log(err);
                done(err);
            });
    }
));

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
    User.forge({ id: id })
        .fetch()
        .then(function (err, user) {
            done(err, user);
        });
});