0

无论如何要为特定操作添加一些中间件?因为据我所知 addPreProcessor 将中间件添加到所有操作中?假设您不想对某些操作进行身份验证或其他检查,有什么解决方案吗?

我有一个短期解决方案,但是如果您可以在定义操作时分配特定的中间件,那就太好了(例如按顺序给出需要运行的中间件名称数组)

我当前的解决方案是保留我需要将中间件应用到它们的所有操作的数组,然后根据 connection.aciton 检查它,但是每个请求仍然通过所有中间件,然后它被传递它不会对我来说听起来效率不高!

exports.middlewares = function(api, next){

    var myImportantMiddleware = function(connection, actionTemplate, next) {

        var actionsToBeChecked = ['deposit'];
        var action = connection.action;

        if(actionsToBeChecked.indexOf(action) > -1) {
                /*  middleware logic 
                next(connection, true); */
        } else {
            next(connection, true);
        }
    }

    api.actions.addPreProcessor(myImportantMiddleware);

    next();
}

提前致谢 !

4

2 回答 2

1

没有必要做这一切!从文档中查看此示例:https ://github.com/evantahler/actionhero-tutorial/blob/master/initializers/middleware.js

exports.middleware = function(api, next){

  var authenticationMiddleware = function(connection, actionTemplate, next){
    if(actionTemplate.authenticated === true){ // <-- HERE
      api.users.authenticate(connection.params.userName, connection.params.password, function(error, match){
        if(match === true){
          next(connection, true);
        }else{
          connection.error = "Authentication Failed.  userName and password required";
          next(connection, false);
        }
      });
    }else{
      next(connection, true);
    }
  }

  api.actions.addPreProcessor(authenticationMiddleware);

  next();
}

是的,所有中间件都会触发所有操作,但您可以告诉中间件检查操作的定义,并查找特定属性。在这种情况下,我们只关心操作是否如下所示:

exports.randomNumber = {
  name: 'randomNumber',
  description: 'I am an API method which will generate a random number',
  outputExample: {
    randomNumber: 0.123
  },

  authenticated: true // <<--- HERE

  run: function(api, connection, next){
    connection.response.randomNumber = Math.random();
    next(connection, true);
  }

};
于 2015-01-11T06:08:48.747 回答
-1

好的,我想我找到了更好的解决方案,我想知道您的意见。

所以我只是添加middlewares : ['middlewareOne', 'middlewareTwo']到我的操作中,执行顺序等于数组中中间件名称的顺序,然后我的中间件初始化程序是这样的

var async = require('async');

exports.middlewares = function(api, next){

    var middlewares = {

        authMiddleware : function(connection, next){
            /* Middleware logic */
        },

        premiumAccessMiddleware : function(connection, next){
            /* Middleware logic */
        },

        adminAccessMiddleware : function(connection, next){
            /* Middleware logic */
        }

    };


    var middlewareProcessor = function(connection, actionTemplate, next){

        var actionMiddlewares = actionTemplate.middlewares;

        async.eachSeries(actionMiddlewares, function(middlewareName, callback){

            var middleware = api.middlewares[middlewareName];

            if(!middleware) throw (new Error("Middleware '"+ middlewareName +"'doesn't exist"));  /* In case I had a typo */

            middleware(connection, function(new_connection, toRender){

                connection = new_connection;

                if(toRender){

                    callback();

                }else{

                    callback('YOU SHALL NOT PASS');
                }

            });

        }, function(err){

            // if(err) return next(connection, false); // see EDIT1

            next(connection, true);

        });

    }

    api.actions.addPreProcessor(middlewareProcessor);

    next();
} 

有什么想法吗?

EDIT1:next(connection, false);不要向用户发送任何内容,我猜您总是想向用户发送错误响应或其他内容,即使执行中间件在其中一个不成功并返回next(connection, false). 在这种情况下,在 eachSeries 最终回调函数中,我想我们总是必须使用next(connection, true);!!

于 2015-01-11T03:21:52.023 回答