2017-05-24 12 views
2

我有节点脚本和后端,该脚本包含某些数据,并从后端得到一些条件。从后端检查条件(if-else)没有eval

对于离node script

var data={ 
    count: 10, 
    length: 27, 
    days: 3 
}; 
var condition = 'count > 10 && length < 3'; // <=== this condition got from backend 
if(... condition ...) { 
    // action 1 
} else { 
    // action 2 
} 

我能不eval条件的结果?因为来自后端evals的数据对服务器不安全。或者有没有办法在沙箱中运行这个条件?

+0

是什么刺痛可能具有价值? –

+1

您遇到架构问题。你应该发送你的条件不是字符串,而是作为对象,像这样''[{field:'count',operator:'>',value:'10'},{field:'length',operator:'>'' ,值:'3'}]' – degr

+0

@degr我可以做到,但如何检查每个条件?以及如何检查这样的条件'(a> 3 &&(b <3 || z> 6))'? – MixerOID

回答

2

我的解决办法是runInNewContext简单的功能,条件安全隔离沙箱中运行与我的变量

var vm = require("vm"); 
function safeEval(code, variables = {}, opts) { 
    var sandbox = Object.assign({ 
     _code_result_: undefined 
    }, variables); 
    vm.runInNewContext('_code_result_=(' + code + ')', sandbox, opts); 
    return sandbox['_code_result_']; 
} 
var data = { 
    count: 10, 
    length: 27, 
    days: 3 
}; 
var condition = 'count >= 10 && length > 3'; // <=== this condition got from backend 
if (safeEval(condition, data)) { 
    // action 1 
} else { 
    // action 2 
} 
1

使用一些评论,像这样的东西可能会帮助你?

var data = {  
    count: 11,  
    length: 27,  
    days: 3  
};  

var fromServer = [{field: 'count', operator: '>', value: '10'}, {field: 'length', operator: '>', value: '3'}];  

if (checkObjConditions(fromServer)) {  
    console.log("yes");  
} else {  
    console.log("no");  
}  

function checkObjConditions(co) {  
    //var conditions = c.split("&&");  
    var isCondition = true;  
    for (var a = 0; isCondition && a < co.length; a++) {  
    //var c = conditions[a].trim().split(",");  
    var r = compare(co[a]['field'], co[a]['operator'], co[a]['value']);  
    console.log(">", r);  
    if (!r)  
     isCondition = false;  
    }  
    return isCondition;  
}  

function compare(a, operator, b) {  
    var ans = false;  
    switch (operator) {  
    case '<':  
     if (data[a] < parseInt(b))  
     ans = true;  
     break;  
    case '>':  
    console.log(data[a], parseInt(b))  
     if (data[a] > parseInt(b))  
     ans = true;  
     break; 
    // ... and other cases also  
    }  
    return ans;  
}