Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node: how to implement isLoggedIn before all routes?

I want to write a helper function isLoggedIn , which is used for judge if the any user has logged in, if logged in, set res.locals.is_logged_in = true.

var isLoggedIn = function(req, res, next) {
    User.findById(sessions.user_id, function(err, user) {
        if (err) throw err;
        return !user ? false : true;
    });
};

then, before all routes, I write

.use(express.static(path.join(__dirname, '/public')))
.use(express.static(path.join(__dirname, '/bower_components')))
.use(flash)
.use(function(req, res, next) {
    if (isLoggedIn(req, res, next)) {
        res.locals.is_logged_in = true;
        res.locals.current_user = '/users/' + req.user._id;
    } else {
        res.locals.is_logged_in = false;
    }

    res.locals.showTests = app.get('env') !== 'production' &&
    req.query.test === '1';

    next();
});

var routes = require('./routes/routes.js');
app.use('/', routes.staticPages());
app.use('/', routes.sessions(sessionHelper));
app.use('/users', routes.users(sessionHelper));

But I realized the findById is an async function, so I cann't get the right behavior in this way.

I tried

var isLoggedIn = function(callback) {
    User.findById(sessions.user_id, function(err, user) {
        if (err) throw err;
        callback(user);
    });
};

.use(function(req, res, next) {
        sessionHelper.isLoggedIn(function(user) {
            if (!user) {
                console.log("no");
                res.locals.is_logged_in = false;
            } else {
                console.log("yes");
                res.locals.is_logged_in = true;
                res.locals.current_user = '/users/' + req.user._id;
            }
        });

        res.locals.showTests = app.get('env') !== 'production' &&
            req.query.test === '1';

        next();
    });

It doesn't work right either: In some routes, I print res.locals.is_logged_in, get the value "undefined", How to resolve this problem?

like image 594
zwb Avatar asked Dec 14 '25 12:12

zwb


1 Answers

You need to you asynchronous call. In your case you should use the callback:

.use(function(req, res, next) {
    sessionHelper.isLoggedIn(function(user) {
        if (!user) {
            console.log("no");
            res.locals.is_logged_in = false;
        } else {
            console.log("yes");
            res.locals.is_logged_in = true;
            res.locals.current_user = '/users/' + req.user._id;
        }

        next(); // next MUST be here in order to continue AFTER db query
    });

    res.locals.showTests = app.get('env') !== 'production' &&
        req.query.test === '1';

    //next(); // remove this from here, as it makes it continue without waiting for db query
});
like image 100
Andrey Popov Avatar answered Dec 17 '25 02:12

Andrey Popov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!