Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用异步身份验证路由和passport.js时未序列化用户_Javascript_Node.js_Cookies_Asynchronous_Express - Fatal编程技术网

Javascript 使用异步身份验证路由和passport.js时未序列化用户

Javascript 使用异步身份验证路由和passport.js时未序列化用户,javascript,node.js,cookies,asynchronous,express,Javascript,Node.js,Cookies,Asynchronous,Express,我有一个单独运行的节点应用程序。如果客户端中没有js,它只是同步运行,使用passport.js设置cookie。当客户端启用js时,则通过rest路由完成身份验证 一切似乎都很好,除了如果我已经通过身份验证并异步设置了Cookie,但随后刷新页面或同步导航到新页面(无论出于何种原因),服务器会使用新的Cookie发送响应,覆盖旧的Cookie,并将用户设置回未经身份验证的状态 // ====================================================

我有一个单独运行的节点应用程序。如果客户端中没有js,它只是同步运行,使用passport.js设置cookie。当客户端启用js时,则通过rest路由完成身份验证

一切似乎都很好,除了如果我已经通过身份验证并异步设置了Cookie,但随后刷新页面或同步导航到新页面(无论出于何种原因),服务器会使用新的Cookie发送响应,覆盖旧的Cookie,并将用户设置回未经身份验证的状态

    // =============================================================================
// AUTHENTICATE (FIRST LOGIN) ==================================================
// =============================================================================

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


app.post('/async/login', function(req, res, next) {

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

        if (err) {
            return res.send(err);
        }

        if (user) {
            user.local = null;
            return res.send(user);

        } else {
            return res.send(info);
        }

    })(req, res, next);


});


 // =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session

// used to serialize the user for the session
passport.serializeUser(function(user, done) {
    done(null, user.id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
        done(err, user);
    });
});

// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
passport.use('local-login', new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField: 'username',
        passwordField: 'password',
        passReqToCallback: true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
    },
    function(req, email, password, done) {
        // asynchronous
        process.nextTick(function() {
            User.findOne({
                'local.email': email
            }).populate({
                path: 'spots comments currentLocation'
            }).exec(function(err, user) {
                // if there are any errors, return the error
                if (err)
                    return done(err);

                // if no user is found, return the message
                if (!user)
                    return done(null, false, req.flash('loginMessage', 'No user found.'));

                if (!user.validPassword(password))
                    return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));

                // all is well, return user
                else

                    User.populate(user, {
                    path: 'spots.bird',
                    model: 'Bird'
                }, function(err, user) {

                    if (err)
                        return done(err);

                    else

                        User.populate(user, {
                        path: 'spots.location',
                        model: 'Location'
                    }, function(err, user) {
                        if (err)
                            return done(err);
                        else
                            console.log(util.inspect(user, showHidden = false, depth = 5, colorize = true));
                        return done(null, user);
                    });
                });

            });
        });

    }));
节点应用程序:

app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: true
}));

app.use(cookieParser());


sessionVars = {
    keys: ['<removed>'],
    //secureProxy: true, // if you do SSL outside of node
    maxAge: 2592000000
};

app.use(session(sessionVars));

app.use(flash());

require('./../modules/auth/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
有人知道为什么吗

更新:异步路由似乎没有调用解释一切的serializeUser函数!。有人知道如何强制序列化吗

如果我尝试直接调用:passport.serializeUseruser,done,那么我需要done参数,它在routes文件中不可用,尽管我可以传递它


是否有人知道,如果使用passport策略,serializeUser将被理所当然地调用?

因此,我发现如果使用自定义形式的authenticate函数:

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);
});
app.post('/login',
  passport.authenticate('local', { successRedirect: '/',
                               failureRedirect: '/login' }));
它似乎没有通过您提供的serializeUser函数传递它。会话的cookie会一直保存在浏览器中,并且会不断更改,即使您已注销,因为它们可能仍在“跟踪”您的行为

如果使用函数的“黑盒”版本:

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);
});
app.post('/login',
  passport.authenticate('local', { successRedirect: '/',
                               failureRedirect: '/login' }));

这是因为它会自动调用serializeUser。

它是否与saveUninitialized或ResSave选项相关?检查有关这些参数的文档,尝试将它们设置为false以查看是否有更改。谢谢@WaldoJeffers。我和这些人玩了一场,但似乎不是。。。但这是一个很好的建议