Express.js 中间件为它上面定义的路由执行

far*_*odg 4 node.js express jwt express-jwt

根据我在此处此处阅读的内容,您放置中间件功能的顺序很重要,因为如果将某些路线放置在路线之前,您可以让某些路线不通过中间件功能,而放置在之后的路线将通过这个中间件功能。

我看到的结果喜忧参半,因为我的开发环境不尊重这一点,而我的生产环境则尊重。代码完全一样。

我想要做的是让我的登录路由不受令牌检查器中间件功能的保护,并让我的其余路由受令牌保护。

这是我的代码:

routes.get('/login', function(req, res) {
    // login user, get token
});

routes.use(function(req, res, next) {
    // check header or url parameters or post parameters for token
    var token = req.headers['access-token'];
    // decode token
    if (token) {
        // validate token
    }
    else if (req.method === 'OPTIONS') {
        next();
    }
    else {
        // if there is no token
        // return an error
        return res.status(403).send({
            success: false,
            message: 'No token provided.'
        });
    }
});

routes.get('/query/:keywords', function(req, res) {
    console.log(req.params.keywords);
    // execute query
});

app.use('/', routes);
Run Code Online (Sandbox Code Playgroud)

/query航线是唯一一个应该要经过令牌中间件的功能是否正确?现在我得到的/login路由也通过令牌中间件功能,这没有意义,因为我不需要令牌来登录。

更好的是,如果有一种方法可以定位我想要保护的路由以及我不想保护的路由,这似乎比必须依赖中间件功能放置位置的“顺序”更好。

Gab*_*ntú 5

首先,在ExpressJS 中遵循这个用法:

多个回调函数可以处理一个路由(确保指定下一个对象)。例如:

app.get('/example/b', function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from B!')
})
Run Code Online (Sandbox Code Playgroud)

你会注意到它的定义与你声明的很接近routes.use(yourFunction(...))。但是,除了遵循您在文档中看到的示例之外,没有真正的理由这样做,不过这是一个很好的开始方式。

然而,这是一个脆弱的实现,express 将允许它的.get() .post()方法中的层次结构,这是正确的,但这是特定于用例的,而不是您正在寻找的。

您需要的是使用双回调配置来实现您的自定义身份验证过程。做这个:

// You can save this function in a separate file and import it with require() if you want

const tokenCheck = function(req, res, next) {
    // check header or url parameters or post parameters for token
    var token = req.headers['access-token'];
    // decode token
    if (token) {
        // validate token
    }
    else if (req.method === 'OPTIONS') {
        next();
    }
    else {
        // if there is no token
        // return an error
        return res.status(403).send({
            success: false,
            message: 'No token provided.'
        });
    }
});


routes.get('/login', function(req, res) {
    // login user, get token [Unprotected]
});

routes.get('/query/:keywords', tokenCheck, function(req, res) {
    console.log(req.params.keywords);
    // execute query [Protected with tokenCheck]
});

app.use('/', routes);
Run Code Online (Sandbox Code Playgroud)

您可能需要使用上面的代码,但它会指导您朝着正确的方向前进,这样您就可以根据需要指定特定的路线来执行该tokenCheck(req, res, next)功能。