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
。
在 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
。