大数据标签 数据校验_动态数据校验之 JSON Schema

背景

一天, 线上 node 服务告警了, 经排查, 发现大量非法请求在扫我们的服务, 这些请求将正常 url 参数替换成各种试探参数, 有尝试 SQL 注入的, 有尝试 XSS 攻击的, 还有夹杂各种随机字符串的, 来势汹汹. 但这些请求在处理的过程中, 都被我们一步步的判断条件过滤掉了, 没有造成大问题. 唯一问题就是 CPU 使用率偏高, 因为我们没有在请求进来的第一个时间去做校验, 这些非法请求进入了我们的业务逻辑触发了一些不必要的运算.

为了不再让这些请求进入运算逻辑, 要为所有接口做参数校验, 对含有非法参数的请求直接返回, 这些参数通过 ctx.req.query 或 ctx.req.body 可以拿到, 一开始, 想着写个简单校验函数处理下, 但接口众多, 得写个通用的才行, 写着写着才发现要兼容所有情况还很麻烦, 比如深层嵌套的 object, 数组, 工作量挺大的.

本着不重复造轮子的原则, google 上一番搜索, 发现了 JSON Schema, 还有 JSON Schema 的 js 库 ajv, 很切合这个场景, 于是用 avj 在请求进来的第一时间, 对 ctx.req.query 和 ctx.req.body 做了校验, 节约了很多时间~

JSON Schema 可以用于接口的数据校验, 表单提交前的校验, 前后端同构的校验, 如果有中间数据处理层, 接收多方数据, 用 JSON Schema 来保证数据一致性也是一个比较好的实践.

JSON Schema 简介

JSON Schema 用来描述某个 JSON 数据应该有什么字段, 这些字段受哪些规则限制, 比如非空, 最大长度, 最小长度, 符合某个正则, 属于哪几个常量等. 

本文会给大家介绍 JSON Schema 的基本概念, 各种常见数据类型的约束写法, 以及通过结合 ajv 库如何在 js 中使用 JSON Schema. 让我们开始吧.

先整体看一下 JSON Schema:

{
      "type": "object",  "properties": {
        "id": { "type": "integer" },    "name": { "type": "string" },    "phone": { "type": "string" },    "hobby": {
            "type": "array",        "items": {
                "type": "string"        }    }  },  "required": ["id", "name"]}

那么, 以下数据就符合上边的 schema:

{
        "id": 0,    "name": "zhangsan",    "phone": "18814166666",    "hobby": ["coding", "music", "game"]}

如果没有 id 或者 name, 或者这些字段的类型不对, 这个数据就不能通过 schema 的校验了

JS 的 JSON Schema 库 ajv

ajv 是对 JSON Schema 支持最全的一个库, 性能在现有的库中也很优越, 排在第二位, 排第一位 djv 没有实现 JSON Schema 的最新特性, 而 ajv 与 djv 性能上很接近, 且 ajv star 数 6.7k, djv 才 236.

ajv 是最优的选择.

基本用法
const Ajv = require('ajv');const ajv = new Ajv()const isValidate = ajv.validate({ type: 'string' }, 123);if (!isValidate) {
        console.log(ajv.errors);    console.log(ajv.errorsText(ajv.errors));}

输出:

[  {
        keyword: 'type',    dataPath: '',    schemaPath: '#/type',    params: { type: 'string' },    message: 'should be string'  }]data should be string

用法简单明了, validate(schema, data), 只需要指定 schema 和 data 即可, schema 就是我们上面说到的 schema, data 就是被校验的数据了.

接下来我们来看 schema 都有哪些规则。

string
{
        "type": "string",    "minLength": 1,    "maxLength": 100,}

以上 schema 表示必须为字符串类型, 最小长度为 1, 最大长度为 100. 此外, 还可以指定正则表达式来做匹配

{
       "type": "string",   "pattern": "^\\w+$"}

以上正则表示只能由英文, 数字, 下划线组成

此外 string 类型还可以指定 JSON Schema 内置的类型, 如

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值