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

Node.js Express.js中间件为上面定义的路由执行,node.js,express,jwt,express-jwt,Node.js,Express,Jwt,Express Jwt,从我所读到的和,您放置中间件功能的顺序很重要,因为您可以让某些路由不通过中间件功能,如果它放置在路由之前,那么放置在路由之后的路由将通过该中间件功能 我看到的结果好坏参半,因为我的开发环境不尊重这一点,而我的prod环境则不尊重这一点。代码完全相同 我试图做的是让我的登录路由不受令牌检查器中间件功能的保护,而让我的其余路由受令牌保护 这是我的密码: routes.get('/login', function(req, res) { // login user, get token });

从我所读到的和,您放置中间件功能的顺序很重要,因为您可以让某些路由不通过中间件功能,如果它放置在路由之前,那么放置在路由之后的路由将通过该中间件功能

我看到的结果好坏参半,因为我的开发环境不尊重这一点,而我的prod环境则不尊重这一点。代码完全相同

我试图做的是让我的登录路由不受令牌检查器中间件功能的保护,而让我的其余路由受令牌保护

这是我的密码:

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);
/query
路由是唯一必须通过令牌中间件功能的路由,对吗?现在我得到的
/login
路径也通过令牌中间件功能,这没有意义,因为我不需要令牌登录


更好的是,如果有一种方法来确定我想要保护的路线和我不想要保护的路线,这似乎比依赖“订单”要好由于路由顺序和登录路由从不调用下一个对象的事实,令牌中间件的应用不应发生在登录路由上。如果没有更多的信息,我们真的无法排除除此之外正在发生的事情,但是您可以中断并查看命中该中间件的req

但是,我们可以为您提供一些信息,说明如何尝试隔离您的。使用中间件以及中间件订单的应用程序如何应用,以便您可以尝试将其与登录路径完全分离,就像您问题的底部一样


当仅将中间件应用于特定路由时,您应注意,order and.use用于在告诉express继续在路由器中寻找在它们之后也将处理请求的其他中间件之前,应回答请求的中间件。如果您只想在几个路由上使用它,可以通过如下方式显式地将其添加到几个路由:

router.get('/route', [ middleware1, middleware2, ..., middlewareX])

这两种模式都会奏效。然而,我发现数组模式更容易接受,因为我可以定义许多我想要应用的中间件,然后为特定的逻辑连接新的中间件,我只需要修改我声明连接的地方,以添加更多功能。然而,很少需要这么多中间件,您应该能够使用其中任何一种

您还可以使用路由器将该中间件划分为路由子集,并将其作为路由器之前路由链的第一个中间件应用

app.use('/user', authentication, userRouter)
或者,您可以将它作为第一个具有.use的中间件放在路由器中,以便它处理所有请求

因此,请记住有关中间件使用的一般提示:

  • 中间件应用程序的订购事项
  • 应基于路由应用的可选中间件应和其他中间件一起应用,以便仅针对该路由
  • 错误处理中间件必须始终排在最后,并且有四个参数(err、req、res、next)

您可以在

中找到有关它的更多信息。首先,请按照以下步骤操作:

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

您会注意到它的定义与您在
路由上声明的内容非常接近。请使用(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);

您可能需要使用上面的代码,但它会引导您正确的方向,这样,您可以指定特定的路径来执行
tokenCheck(req、res、next)
根据需要运行。

最简单的方法是使用路由器中间件来确定需要身份验证的路由和不需要身份验证的路由。因为所有路由器都是中间件,所以我们可以像其他中间件一样实现它们。确保我们将路由器和路由按照我们希望评估路由的顺序放置

在下面的示例中,Express服务器有2个路由器,一个LoginRouter和一个ApiRouter

  • LoginRouter
    -当接收到对
    POST/login
    的请求时,生成一个令牌,并将其返回给请求者,以供后续在
    /api
    路由中使用
  • ApiRouter
    -包装所有其他路由器,集中需要全局应用于/api下所有路由的中间件。只有经过身份验证的请求才能访问
只有当标头中包含令牌并且该令牌是从LoginRouter获得时,才可以访问API路由器。LoginRouter不需要身份验证

通过此设置,您将通过ApiRouter上的
.use()
在授权中间件之后继续向API路由器添加路由器

以下由其他路由器组成的路由器模式功能强大、可扩展且易于维护

server.js LoginRouter-/routes/login.js ApiRouter-/routes/api/index.js UsersRouter-/routes/api/users
应用于前一个的路径永远不会发生。。。从来没有。JavaScript在这一点上是程序化的,全局中间件不应应用于登录路由。。。您是否可以提供任何错误输出?我猜不是
/login
请求击中了您的令牌检查中间件。您应该在该中间件中执行
console.log(req.url)
,以查看命中它的是什么。非常
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!')
})
// 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);
const express = require('express')
const bodyParser = require('bodyParser')
const ApiRouter = require('./routes/api')
const LoginRouter = require('./routes/login')
const port = process.env.PORT || 1337

const server = express()

server.use(bodyParser.json())

server.use('/login', LoginRouter)
server.use('/api', ApiRouter)

server.listen(port, () => console.log(`Listening on ${port}`))
const router = require('express').Router()

router.post('/', (req, res) => {    
    // Validate Credentials
    // some validation code...

    // Then create the token for use later in our API
    let token = '...'

    // Response 200 OK with the token in the message body   
    return res.status(200).send({token})
})

module.exports = router
const router = require('express').Router()    
const UsersRouter = require('./routes/api/users')

router.use((req, res, next) => {
    let authorizationHeader = req.headers['authorization'] || req.headers['Authorization'] // handle lowercase
    let [, token] = authorizationHeader.split(' ')
    if (!token) {
        return res.sendStatus(403) // Forbidden, you're not logged in
    } else {
        // validate the token    
        if (!tokenIsValid) {
            return res.sendStatus(403) // Forbidden, invalid token
        } 

        // Everything is good, continue to the next middleware
        return next()
    }
})

router.use('/users', UsersRouter)

module.exports = router
const router = require('express').Router()

router.get('/', (req, res) => {
    // We only get here if the user is logged in     
    return res.status(200).json({users: []})
})

module.exports = router