node.js - express/connect 中间件的控制顺序

标签 node.js express connect.js

我正在尝试添加身份验证中间件,以防止访问网站的一部分:

app = express()
    .get('/api/test', function (req, res) { ... })
    .use('/api', function (req, res, next) {
        if (req.param('key')) {
            next();
        } else {
            res.json(401, {
                message : 'Authentication failed'
            });
            res.end();
        }
    })
    .get('/api/data', function (req, res) { ... });

我期望对/api/data 的调用将首先由 key 检查器处理,然后(如果成功)由/api/data 处理程序处理。而是先由“/api/data”处理请求。

检查器似乎适用于/api/something_that_does_not_exist,但不适用于/api/something_that_exist。

也许我遗漏了 express/connect 文档中的某些内容?

更新 我已经跟踪到第一个 get/post 调用初始化路由器中间件,因此它首先执行。

最佳答案

一旦您声明了路由,Express 就会在设置应用程序时将 router 中间件插入到中间件堆栈中。

在您的情况下,因为您在插入 key 检查中间件之前插入了 .get('/api/test', ...),所以路由器中间件将被插入并将优先(也对于您稍后声明的 /api/data 路由)并且您的 key 检查器永远不会被调用。

这里有两种解决方法:

// separate middleware, used for all routes that need checking
var keyChecker = function(req, res, next) {
  ...
};
app.get('/api/test', function(req, res) { ... });
app.get('/api/data', keyChecker, function(req, res) { ... });

// or, as an alternative, create a 'catch-all' route between the routes that don't
// need to be checked, and the ones that should; this will also match non-existing
// routes (like '/api/foobar'), which might or might not be an issue;
app.get('/api/test', function(req, res) { ... });
app.all('/api/*', function(req, res, next) { // 'all' means 'all methods'
  // keychecker code
});
app.get('/api/data', function(req, res) { ... });

第三种解决方案可能是在 key 检查中间件本身中显式检查 /api/test (req.path === '/api/test') , 如果匹配就调用 next()

关于node.js - express/connect 中间件的控制顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15973059/

相关文章:

javascript - 是否可以为 Express 中的给定模板引擎添加全局渲染回调?

javascript - 使用 gulp-jade 和 gulp-useref 时,CSS 和 JS 文件不会缩小和连接

node.js - Node JS + Express - 将整个项目文件夹移动到同一驱动器上的不同目录

javascript - 在javascript中使用child_process执行shell命令

node.js - 如何在 Express.js 或 Connect.js 中配置多个子域

javascript - 如何使用 ES6 语法导入 pg-promise?

node.js - 如何连接到 docker 容器的本地主机(从容器内部)

python - 结合 python flask 和 express.js

Node.js/Connect 使用现有的 Connect.SID

javascript - 从 Node JS connect.js 获取服务器的端口