在Express中使用特定中间件用于除特定路径之外的所有路径

时间:2012-10-16 19:01:00

标签: node.js routes express middleware

我在node.js中使用带有一些中间件函数的Express框架:

var app = express.createServer(options);
app.use(User.checkUser);

我可以使用带有附加参数的.use函数仅在特定路径上使用此中间件:

app.use('/userdata', User.checkUser);

是否可以使用路径变量,以便中间件用于除特定路径之外的所有路径,即根路径?

我正在考虑这样的事情:

app.use('!/', User.checkUser);

除了根路径外,总是调用User.checkUser

7 个答案:

答案 0 :(得分:87)

我会将checkUser中间件添加到我的所有路径中,但主页除外。

app.get('/', routes.index);
app.get('/account', checkUser, routes.account);

app.all('*', checkUser);

function checkUser(req, res, next) {
  if ( req.path == '/') return next();

  //authenticate user
  next();
}

您可以使用下划线对其进行扩展,以在未经过身份验证的路径数组中搜索req.path:

function checkUser(req, res, next) {
  var _ = require('underscore')
      , nonSecurePaths = ['/', '/about', '/contact'];

  if ( _.contains(nonSecurePaths, req.path) ) return next();

  //authenticate user
  next();
}

答案 1 :(得分:8)

不是直接注册User.checkUser作为中间件,而是注册一个新的帮助函数,比如checkUserFilter,它会在每个URL上调用,但只在给定的URL上传递给userFiled`。例如:

var checkUserFilter = function(req, res, next) {
    if(req._parsedUrl.pathname === '/') {
        next();
    } else {
        User.checkUser(req, res, next);
    }
}

app.use(checkUserFilter);

理论上,您可以提供app.use的正则表达式路径。例如:

app.use(/^\/.+$/, checkUser);

在Express 3.0.0rc5上尝试过它,但它不起作用。

也许我们可以open a new ticket并建议将其作为一项功能?

答案 2 :(得分:6)

您也可以为每条路线设置中间件。

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

答案 3 :(得分:2)

使用

ko.observableArray

这传递除/之外的任何URL。除非,它对我有用。

一般

app.use(/^(\/.+|(?!\/).*)$/, function(req, resp, next){...

(见How to negate specific word in regex?

希望这有帮助

答案 4 :(得分:1)

使用名为express-unless的该库

除非路径为index.html,否则要求对每个请求进行身份验证。

app.use(requiresAuth.unless({
  path: [
    '/index.html',
    { url: '/', methods: ['GET', 'PUT']  }
  ]
}))

路径可以是字符串,正则表达式或其中任何一个的数组。它也可以是一个对象数组,它是URL和方法密钥对。如果请求路径或路径和方法匹配,则中间件将不会运行。

该库肯定会为您提供帮助。

答案 5 :(得分:0)

@chovy的解决方案是最好的。

另一个解决方案是:

我正面临类似的问题。因此,我要做的就是将“路​​由”文件中的功能拆分为不同的文件,然后分别导出它们。同样,我将它们分别导入“服务器”文件中,并为各个路由调用了中间件。但是我不建议大规模使用,我有一个少于10条路线的小项目,所以我不介意这样做。对于缩放,我会选择chovy的方法。

答案 6 :(得分:0)

解决方案是使用设置api和中间件的顺序。在您的情况下,它必须是这样的。

 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!")
    );

这是一个完整的例子。

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