Express 应用程序 - 对许多但不是所有请求执行功能

Express app - Execute function on many but not all requests

在 node express 应用程序中对许多但不是所有请求调用函数的最佳方法是什么? (一个例子是检查用户当前是否登录的函数)

我所做的是定义一个导出 checkLogin(...) 函数的模块,并在每个相应的 api 请求上调用此函数。例如:

模块授权:

module.exports = {
    checkLogin: function(req, res, next) {
        if (req.session.hasOwnProperty('user')) {
            //if the user is logged in we pass through
            next();
        } else if (req.cookies.user == undefined || req.cookies.pass == undefined) {
            res.render('login', { title: 'Login' });
        } else {
            User.checkLogin(req.cookies.user, req.cookies.pass, true, function(o) {
                if (o != null) {
                    req.session.user = o;
                    next();
                } else {
                    res.render('login', { title: 'Login' });
                    return;
                }
            });
        }
    }
};

/index 的路由:

//...
var auth = require('../middlewares/auth.js');
//...
    router.get('/index', auth.checkLogin, function(req, res) {

        //if we passed the auth.checkLogin step we render the index page
        res.render('index', {
            title: 'Index',
            udata: req.session.user
        });

    });

在另一个路由文件中:

//...
var auth = require('../middlewares/auth.js');
//...
        router.get('/user/someAPICall', auth.checkLogin, function(req, res) {
           ...
        });

这是要走的路还是有更好的方法?我可以定义一个中间件函数,我可以在每个路由中使用 app.use(function(){..}) 包含它。问题是这个路由的每个请求都会通过这个函数,这不是我想要的。

路由器 (http://expressjs.com/en/guide/routing.html) 是设计应用程序的好方法。您可以将 URL 路径视为命名空间,并为需要用户身份验证的命名空间创建路由器。 很可能您的 /index 主页不需要立即重定向到登录,因为它用于演示目的;但如果需要,只需像上面那样包含 auth.checkLogin

对于您需要对用户进行身份验证的所有其他内容(例如 /user/* 下的所有内容),您最好创建一个作用域路由器

const router = express.Router();
router.use(auth.checkLogin);
router.get('/someAPICall', fn1, fn2);
router.get('/someOtherAPICall', fn3, fn4);

然后在您的父路由器或主应用程序中,只包含路由器:

app.use('/user', router);

这就像定义:

app.use('/user/someAPICall', [auth.checkLogin, fn1, fn2]);
app.use('/user/someOtherAPICall', [auth.checkLogin, fn3, fn3]);

这为您提供了创建模块化路由处理程序的优势 - 这使它们更易于调整、重用等 - 同时将保持 auth.checkLogin,尽管在进入路由器时始终执行,仅针对路由器定义的路径。

简而言之,方法是:"execute function on all routes inside the router, but not on all the app requests"。

如果您不能以这种方式重新设计您的路线,那么是的,您将始终需要在处理程序列表中为您只想使用的路径包含 auth.checkLogin