首页 > 解决方案 > Node ExpressJS:中间件 URL 路由响应与路由目的地

问题描述

router.use((req, res, next) => {
    if(req.originalUrl == '/api/test'){
        //does stuff
        res.send(result);
    }
    next();
})

对比

route.get('/api/test', (req, res) => {
   //does stuff
   res.send(result)
}

我对整个 HTTP Web 应用程序安全行为相当不熟悉,所以我想问一下,如果我使用第一种方法来解决某些路由目的地,是否有任何漏洞或缺点?

标签: javascriptnode.jsapiexpress

解决方案


我对整个 HTTP Web 应用程序安全行为相当不熟悉,所以我想问一下,如果我使用第一种方法来解决某些路由目的地,是否有任何漏洞或缺点?

router.use()和和之间有两个主要区别router.get(),一个在这里有点相关:

  1. router.use()匹配任何 http 动词,例如 GET、POST、PUT、OPTION、PATCH 等……而router.get()仅匹配 GET 请求,router.post()仅匹配 POST 请求等。

  2. router.use()使用“松散”匹配算法,其中请求的路由只需从路由上的路径指定开始,而不是完全匹配。

对于第一点,您的中间件处理程序正在res.send(response)为所有请求路径为/api/test. 这可能不是您想要的,也不是您应该如何编写代码。您应该让您的代码仅响应您实际打算支持的路径的 http 动词并做一些有用的事情。其他动词可能应该以 4xx 状态代码响应(如果您没有处理程序,这将是 Express 中的默认值)。

对于第二点,您的中间件处理程序是通用的(没有设置路径)并且您已经在检查整个路径,因此该点不相关。

加上一点点,我想说你的中间件方法很好。我会添加一个检查req.method

router.use((req, res, next) => {
    if(req.method === "GET" && req.originalUrl == '/api/test'){
        //does stuff
        res.send(result);
        // return so the rest of the route handler is not executed
        // and we don't call next()
        return;
    }
    next();
});

All that said, you can also probably solve your problem in a bit more generic way. For example, if you put a specific route definition in front of this middleware, then it will automatically be exempted from the middleware as it will get processed before the middleware gets to run. Routes in Express are matched and run in the order they are declared.

router.get('/api/test', (req, res) => {
   //does stuff
   res.send(result)
});

router.use((req, res, next) => {
    // do some middleware prep work on all requests that get here
    // ...
    next();
});

// other route definitions here that can use the results of the prior middleware

For example, this is very common if you have some routes that need authentication and others that do not. You put the non-authenticated routes first, then place the authentication middleware, then define the routes that want to be behind the authentication check.


推荐阅读