[英]Use specific middleware in Express for all paths except a specific one
I am using the Express framework in node.js with some middleware functions:我在 node.js 中使用带有一些中间件功能的 Express 框架:
var app = express.createServer(options);
app.use(User.checkUser);
I can use the .use
function with an additional parameter to use this middleware only on specific paths:我可以使用带有附加参数的.use
function 来仅在特定路径上使用此中间件:
app.use('/userdata', User.checkUser);
Is it possible to use the path variable so that the middleware is used for all paths except a specific one, ie the root path?是否可以使用路径变量,以便中间件用于除特定路径(即根路径)之外的所有路径?
I am thinking about something like this:我在想这样的事情:
app.use('!/', User.checkUser);
So User.checkUser
is always called except for the root path.所以User.checkUser
总是被调用,除了根路径。
I would add checkUser middleware to all my paths, except homepage.我会将 checkUser 中间件添加到我的所有路径中,除了主页。
app.get('/', routes.index);
app.get('/account', checkUser, routes.account);
or要么
app.all('*', checkUser);
function checkUser(req, res, next) {
if ( req.path == '/') return next();
//authenticate user
next();
}
You could extend this to search for the req.path in an array of non-authenticated paths:您可以扩展它以在非身份验证路径数组中搜索 req.path:
function checkUser(req, res, next) {
const nonSecurePaths = ['/', '/about', '/contact'];
if (nonSecurePaths.includes(req.path)) return next();
//authenticate user
next();
}
Instead of directly registering User.checkUser
as middleware, register a new helper function, say checkUserFilter
, that gets called on every URL, but passed execution to userFiled` only on given URLs.不是直接将User.checkUser
注册为中间件,而是注册一个新的辅助函数,比如checkUserFilter
,它会在每个 URL 上调用,但仅在给定的 URL 上将执行传递给 userFiled`。 Example:例子:
var checkUserFilter = function(req, res, next) {
if(req._parsedUrl.pathname === '/') {
next();
} else {
User.checkUser(req, res, next);
}
}
app.use(checkUserFilter);
In theory, you could provide regexp paths to app.use
.理论上,您可以提供app.use
表达式路径。 For instance something like:例如类似的东西:
app.use(/^\/.+$/, checkUser);
Tried it on express 3.0.0rc5, but it doesn't work.在 express 3.0.0rc5 上尝试过,但不起作用。
Maybe we could open a new ticket and suggest this as a feature?也许我们可以开一张新票并建议将此作为一项功能?
You can set the middleware on each route also.您也可以在每个路由上设置中间件。
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
Use采用
app.use(/^(\/.+|(?!\/).*)$/, function(req, resp, next){...
This pass any url apart from /.这会传递除 / 之外的任何 url。 Unless, it works for me.除非,它对我有用。
In general一般来说
/^(\/path.+|(?!\/path).*)$/
(see How to negate specific word in regex? ) (请参阅如何否定正则表达式中的特定单词? )
Hope this helps希望这可以帮助
Use this library called express-unless使用这个名为express-unless 的库
Require authentication for every request unless the path is index.html.除非路径是 index.html,否则要求对每个请求进行身份验证。
app.use(requiresAuth.unless({
path: [
'/index.html',
{ url: '/', methods: ['GET', 'PUT'] }
]
}))
Path it could be a string, a regexp or an array of any of those. Path 它可以是字符串、正则表达式或其中任何一个的数组。 It also could be an array of object which is URL and methods key-pairs.它也可以是一个对象数组,它是 URL 和方法密钥对。 If the request path or path and method match, the middleware will not run.如果请求路径或路径与方法匹配,则中间件将不会运行。
This library will surely help you.这个图书馆肯定会帮助你。
The solution by @chovy is the best. @chovy 的解决方案是最好的。
Another solution is:另一种解决方案是:
I was facing a similar problem.我面临着类似的问题。 So what I did was to split the functions in the "routes" file into different files and export them separately.所以我所做的是将“路由”文件中的功能拆分为不同的文件并分别导出。 Likewise I imported them in the "server" file separately and called the middlewares for the respective routes.同样,我将它们分别导入到“服务器”文件中,并为各自的路由调用了中间件。 But I wouldn't recommend this on a large scale, I had a small project of less than 10 routes so I didn't mind doing it.但是我不会大规模推荐这个,我有一个不到10条路线的小项目所以我不介意这样做。 For scaling I would go for chovy's method.对于缩放,我会选择chovy的方法。
The solution is to use order of setting api and middleware.解决方案是使用设置api和中间件的顺序。 In your case it must be something like this.在你的情况下,它必须是这样的。
var app = express.createServer(options);
// put every api that you want to not use checkUser here and before setting User.checkUser
app.use("/", (req, res) => res.send("checkUser middleware is not called"));
app.use(User.checkUser);
// put every api that you want use checkUser
app.use("/userdata", User.checkUser, (req, res) =>
res.send("checkUser called!")
);
This is a full example.这是一个完整的例子。
const express = require("express");
const app = express();
const port = 3002;
app.get("/", (req, res) => res.send("hi"));
app.use((req, res, next) => {
console.log("check user");
next();
});
app.get("/checkedAPI", (req, res) => res.send("checkUser called"));
app.listen(port, () => {
console.log(`Server started at port ${port}`);
});
Thing that worked for me is to init single route you want before initializing for-all check, for example:对我有用的是在初始化 for-all 检查之前初始化你想要的单一路由,例如:
var app = express.createServer(options);
app.get('/', routes.index);
app.use(User.checkUser);
My personal example is this and works:我个人的例子是这样的并且有效:
const app = express();
...
app.use('/api/flow', flowLimiter, flowRouter);
app.use(csurf({
cookie: false,
}));
...
So csurf
is applied an all routes except api/flow
- where I use sendBeacon, so I couldn't apply headers with tokens to it.因此csurf
应用于除api/flow
之外的所有路由 - 我在其中使用 sendBeacon,因此我无法将带有标记的标头应用于它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.