【问题标题】:Selectively apply middleware in express在 express 中选择性地应用中间件
【发布时间】:2017-07-05 20:18:41
【问题描述】:

我的路由器中有一个路由/users 作为父后缀,所有后续路由都将附加父路由,例如。 /users/details

在我的 app.js 中

app.use('/api/v1/users', userRoutes);

在我的用户路由中

import express from 'express';
import users from '../controllers/user_controller';

import { authenticateRoute, authenticateSignedRoute, aclAuthenticator } from './../middlewares/AuthenticationMiddleware';

const router = express.Router();


//user routes
router.get('/details', authenticateRoute, aclAuthenticator, users.getDetails);
router.get('/posts', authenticateRoute, aclAuthenticator, users.getPosts);


module.exports = router;

我想做什么

有没有办法让我将 authenticateRoute 和 aclAuthenticator 中间件添加到父前缀路由,然后对于一个特定的路由有一个例外,即只应用第三个中间件而不是前两个。

例如 app.use('/api/v1/users', authenticateRoute, aclAuthenticator, userRoutes);

我的新路由器文件

router.get('/details', applyOnlyThisMiddleWare, users.getDetails);
router.get('/posts', No MiddleWareAtAll, users.getPosts);

我基本上是想覆盖最初的中间件,这可能吗?

【问题讨论】:

    标签: node.js express middleware


    【解决方案1】:

    我所知道的唯一方法是将前两个中间件直接应用到您的路由器,不带路径前缀:

    router.use(middleware1, middleware2);
    

    然后,在每个中间件中,检查 URL 的路径,如果它是您要跳过这些中间件的特殊路径,则只需调用 next()

    if (req.path.indexOf("/somepath") === 0) { return next() };
    

    然后,你可以只为你感兴趣的路径注册你的第三个中间件:

    router.use("/somepath", middleware3);
    

    前两个中间件会跳过您希望他们跳过的中间件,第三个只会在您的特定路线上被调用。

    【讨论】:

    • 这不会使代码变得非常混乱,基于路由的检查会造成混乱。它也必须通过正则表达式来完成。如果我有/user/1 的路径,这将不断变化。?
    • @NitishPhanse - 对于您所描述的,这将是两条路线中添加的一行代码(请参阅我添加到我的答案中的代码行)。路线定义是包容性的,而不是排他性的,所以我不知道你会怎么做。一种更简洁的解决方法是修复您的 URL 设计,这样您就不会首先创建这种情况,以便中间件 3 更容易与中间件 1 和中间件 2 分离(就像在一个完全独立的路由器上一样)。
    • 完全同意你的观点。我只是想知道异常列表是否会增长到 10 个 url,那么我将不得不处理一个数组。你建议什么 url 结构可以处理这个问题?
    • @NitishPhanse - 如果需要不同中间件的 URL 具有不同的路径根,那么很容易针对它们定位单独的中间件。我不知道您的网址/网站的结构如何提供比这更具体的内容。
    【解决方案2】:

    这就是我明确禁用特定路由的中间件的方式

    'use strict';
    
    const ExpressMiddleware = ( req, res, next ) => {
    
        // dont run the middleware if the url is present in this array
        const ignored_routes = [
            '/posts',
            '/random-url',
        ];
    
        // here i am checking for request method as well, you can choose to remove this
        // if( ! ignored_routes.includes(req.path) ) {
        if( req.method === 'GET' && ! ignored_routes.includes(req.path) ) {
            // do what you gotta do.
            // next();
        }
        else {
            next();
        }
    
    }
    
    
    export default ExpressMiddleware;
    

    在你的服务器/路由文件中

    app.use( ExpressMiddleware );
    

    当然,如果您使用动态路由,您可能需要更改代码.. 但这应该不难。

    【讨论】:

    • @NitishPhanse 是的,你可以。
    • 同样在这种情况下,如果不满足条件,您将如何链接中间件。还是应该在每个中间件中添加此检查
    • 就像你通常链接其他中间件一样链接,你也可以全局应用这个,所以中间件将针对所有路由而不是排除路由运行。你也可以相反,它只会如果 url 存在于数组中,则运行,否则它将被忽略。做最适合您需求的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多