2015-01-02 24 views
5

Tworzę aplety RESTful z node.js i express/koa.Jak filtrować obiekty JSON według "schematu"

Chcę odfiltrować dane wejściowe JSON - ze względów bezpieczeństwa, aby mieć tylko potrzebne właściwości specyficzne dla firmy. Po filtrowaniu odbywa się walidacja specyficzna dla firmy.

Jak mogę odrzucić niepożądane właściwości obiektu JSON/JS - tj. Właściwości spoza schematu bazy danych, a także puste właściwości?

Odpowiedz

4

Myślę, że joi to dobra biblioteka do sprawdzania poprawności i normalizacji. Możesz też czasami uciec z czymś tak prostym, jak _.pick z lodash/podkreślenia.

1

Z dokumentacji joi.validate() może usuwać pola, ale tylko pola będące obiektami. Napisałem to, avialable w gist, który wydaje się działać dobrze. Zwraca nowy obiekt zawierający tylko te pola w obiekcie porównania, które mają taką samą nazwę i typ odpowiedniego pola w obiekcie schematu:

// Recursively strip out fields in objects and subobjects 
function stripFields(schema, obj) { 
    var newObj = {}; 

    var schemaType = schema.constructor.name; 
    var objType = obj.constructor.name; 

    // If types match and this property is not an Object, return the value 
    if (schemaType !== "Object") { 
    if(schemaType === objType) { 
     return obj; 
    } else { 
     return null; 
    } 
    } 

    var keys = Object.keys(schema); 
    keys.forEach(function(key) { 
    if(key in obj) { 
     // Get instance names for properties 
     var schemaConstructor = schema[key].constructor.name; 
     var objConstructor = obj[key].constructor.name; 

     // Only copy fields with matching types. 
     if (schemaConstructor === objConstructor) { 
     // Handle cases with subObjects 
     if (objConstructor === "Object") { 
      var res = stripFields(schema[key], obj[key]); 
      if (res !== null) { 
      newObj[key] = res; 
      } 
     } else { 
      // Just copy in non-Object properties (String, Boolean, etc.) 
      newObj[key] = obj[key]; 
     } 
     } 
    }; 
    if (newObj === {}) { 
     return null; 
    } 
    }); 
    return newObj; 
} 

następujące przypadki testowe poprawnie strip nieprawidłowe pola:

var stripFields = require("./stripfields"); 

var schema = { 
    a: 1, 
    b: 1, 
    c:{ 
     foo:"bar", 
     obj:{nestedField:1} 
    }, 
    d:[1] 
}; 

var testObj1 = { 
    a: 7, 
    b: 8, 
    c:{ 
     foo:"bar" 
    }, 
    d:[4,5] 
}; 

var testObj2 = { 
    a: 1, 
    b: 2, 
    c:{ 
     foo:"bar", 
     obj:{nestedField:213} 
    }, 
    d:[1,3,4], 
    e:"someOtherField" 
}; 

var testObj3 = { 
    a: 1, 
    c:{ 
     foo:"some string", 
     bar:1 
    }, 
    d:"string instead of array" 
}; 


var res1 = stripFields(schema, testObj1); 
var res2 = stripFields(schema, testObj2); 
var res3 = stripFields(schema, testObj3); 
var res4 = stripFields([1,2,3], ["a"]); 

console.log("Results:"); 
console.log(res1); 
console.log(res2); 
console.log(res3); 
console.log(res4); 

Wyniki:

Results: 
{ a: 7, b: 8, c: { foo: 'bar' }, d: [ 4, 5 ] } 
{ a: 1, 
    b: 2, 
    c: { foo: 'bar', obj: { nestedField: 213 } }, 
    d: [ 1, 3, 4 ] } 
{ a: 1, c: { foo: 'some string' } } 
[ 'a' ] 
Powiązane problemy