2014-10-06 14 views
5

Mục tiêu của tôi là tạo một chỉ mục chỉ số cho bài đăng. Người dùng có thể chỉ định một số thông số truy vấn (ví dụ: thẻ, loại) nhưng không thể chỉ định các thông số khác. Để làm rõ:Hapijs và Joi: xác thực thông số truy vấn với sự hiện diện: 'bị cấm'

Đây là okay:

/posts 
/posts?tags=food 
/posts?type=regular&tags=stackoverflow 

Đây không phải là okay:

/posts?title=Hello 

Đây là gói HAPI config:

servers: [ 
     { 
      host: 'localhost', 
      port: 3000, 
      options: { 
       labels: ["api"], 
       validation: { 
        abortEarly: false, 
        presence: 'forbidden' 
       } 
      } 
     } 
    ], 

Xin lưu ý tùy chọn presence: forbidden.

Đây là tuyến đường config:

handler: function (request, reply) { 
    Post.find(request.query, function (err, posts) { 
     if(err) { 
      console.log(err); 
     } 

     reply(posts); 
    }); 
}, 
validate: { 
    query: { 
     type: Joi.string().optional(), 
     tags: Joi.string().optional() 
    } 

} 

Ý tưởng của tôi là xác nhận sẽ cho phép bất kỳ tập hợp con của typetags params (bao gồm cả truy vấn trống). Tuy nhiên, sau khi thực hiện bất kỳ yêu cầu được phép nào, tôi nhận được một lỗi sau:

{ 
    "statusCode": 400, 
    "error": "Bad Request", 
    "message": "value is not allowed", 
    "validation": { 
     "source": "query", 
     "keys": [ 
      "value" 
     ] 
    } 
} 

Tại sao lại như vậy? Tất nhiên, không có khóa nào có tên là value. Làm cách nào để xác thực hoạt động theo cách tôi muốn?

Trả lời

8

Nếu bạn xác định đối tượng giản đồ không phải kiểu, Joi chuyển đổi nội bộ thành loại object(). Vì vậy, sơ đồ này:

var schema = { 
    type: Joi.string().optional(), 
    tags: Joi.string().optional() 
}; 

trở thành:

var schema = Joi.object().keys({ 
    type: Joi.string().optional(), 
    tags: Joi.string().optional() 
}); 

Bởi vì bạn thiết lập presence-forbidden trong cài đặt máy chủ, nó được áp dụng cho các loại đối tượng, do đó schema trở thành:

var schema = Joi.object().forbidden().keys({ 
    type: Joi.string().optional(), 
    tags: Joi.string().optional() 
}); 

Như bạn có thể thấy nó đánh dấu đối tượng chính bị cấm mà sẽ không cho phép bất kỳ giá trị nào ngoại trừ undefined:

var Joi = require('joi'); 

var schema = Joi.object().forbidden().keys({ 
    type: Joi.string().optional(), 
    tags: Joi.string().optional() 
}); 

var value = {}; 

Joi.validate(value, schema, { presence: 'forbidden' }, function (err, value) { 

    console.log(err); 
}); 

Nó ra:

{ [ValidationError: value is not allowed] 
    name: 'ValidationError', 
    details: 
    [ { message: 'value is not allowed', 
     path: 'value', 
     type: 'any.unknown' } ], 
    _object: {}, 
    annotate: [Function] } 

Vì vậy, những gì bạn cần làm là để đánh dấu đối tượng chính hoặc required hoặc optional để ghi đè forbidden:

validate: { 
    query: Joi.object().required().keys({ 
     type: Joi.string().optional(), 
     tags: Joi.string().optional() 
    }) 
} 
+0

Cảm ơn bạn! Câu trả lời này đã xóa một vài câu hỏi khác mà tôi đã có. Có vẻ như những gì tôi thực sự muốn là thiết lập toàn cầu là sự hiện diện: 'bắt buộc'. Tôi đã không nhận ra rằng thiết lập 'cấm' là nghiêm ngặt. – zir

Các vấn đề liên quan