2017-05-24 10 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;  
}