使用async auth route和passport.js时,用户未序列化

时间:2014-08-05 16:12:56

标签: javascript node.js cookies asynchronous express

我有一个独立运行的节点应用程序。如果客户端没有js,它只是同步操作,使用passport.js设置cookie。当客户端启用js时,auth通过休息路径完成。

一切似乎都很好,除非我已经异步验证(并设置了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.serializeUser(用户,已完成),那么我需要done参数,这在routes文件中不可用(虽然我可以通过);

是否有人知道serializeUser是否应该通过护照策略进行调用?

1 个答案:

答案 0 :(得分:0)

所以我发现如果你使用身份验证功能的自定义形式:

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);
});

它似乎无法通过您提供的serializeUser函数传递它。会话的Cookie会保留在您的浏览器中并随时更改,即使您已经注销,因为它们可能仍在跟踪&#39;你的行为。

如果您使用&#39;黑匣子&#39;功能版本:

app.post('/login',
  passport.authenticate('local', { successRedirect: '/',
                               failureRedirect: '/login' }));

有效,因为它会自动调用serializeUser。