是否可以在特定的操作中添加一些中间件?因为据我所知,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();
}提前感谢!
发布于 2015-01-11 14:08:49
不需要做所有这些事情!查看文档中的这个示例: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-11 11:21:52
好的,我想我找到了一个更好的解决方案,我想知道你的意见。
所以我将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); !!
https://stackoverflow.com/questions/27883321
复制相似问题