>  기사  >  웹 프론트엔드  >  Controller 계층의 Node는 어떻게 데이터 검증을 수행하나요?

Controller 계층의 Node는 어떻게 데이터 검증을 수행하나요?

青灯夜游
青灯夜游앞으로
2020-09-02 10:43:491907검색

Controller 계층의 Node는 어떻게 데이터 검증을 수행하나요?

【동영상 튜토리얼 추천: node js tutorial

유머스러운 백엔드 프로그래머들은 대개 자신을 CURD Boy라고 비웃습니다. 특정 스토리지 리소스에 대한 추가, 삭제, 수정 및 조회를 의미하는 CURD는 완전히 데이터 지향적인 프로그래밍입니다.

훌륭합니다. 데이터 지향 프로그래밍은 종종 비즈니스에 대한 더 철저한 이해로 이어져 더 높은 품질의 코드를 작성하고 버그를 줄입니다. 데이터 중심 프로그래밍이기 때문에 더티 데이터의 출현을 방지하고 데이터 검증을 강화하는 것이 더욱 필요합니다. 그렇지 않으면 프런트엔드 데이터 검증을 신뢰해야 할까요? 결국 프런트엔드 데이터 검증은 UI 레이어에서 보다 사용자 친화적인 피드백을 위해 사용자에게 직접 전달됩니다.

데이터 검증 레이어

백엔드는 비즈니스 로직을 강조하기 때문에 다양한 레벨로 나뉘며, 제가 경험한 백엔드 프로젝트는 Controller, Service로 나누어집니다. , Model, Helper, Entity 등 다양한 이름의 레이어가 있습니다. 하지만 여기에는 백엔드의 최상위 레이어에 서서 클라이언트가 전송한 데이터를 직접 수신하는 Controller라는 레이어가 있어야 합니다. ControllerServiceModelHelperEntity 等各种命名的层,五花八门。但这里肯定有一个层称为 Controller,站在后端最上层直接接收客户端传输数据。

由于 Controller 层是服务器端中与客户端数据交互的最顶层,秉承着 Fail Fast 的原则,肩负着数据过滤器的功能,对于不合法数据直接打回去,如同秦琼与尉迟恭门神般威严。

数据校验同时衍生了一个半文档化的副产品,你只需要看一眼数据校验层,便知道要传哪些字段,都是些什么格式。

以下都是常见的数据校验,本文讲述如何对它们进行校验:

  1. required/optional
  2. 基本的数据校验,如 number、string、timestamp 及值需要满足的条件
  3. 复杂的数据校验,如 IP、手机号、邮箱与域名
const body = {
  id,
  name,
  mobilePhone,
  email
}

作者接触过一个没有数据校验层的后端项目,if/else 充斥在各种层级,万分痛苦,分分钟向重构。

JSON Schema

JSON Schema 基于 JSON 进行数据校验格式,并附有一份规范 json-schema.org,目前 (2020-08) 最新版本是 7.0。各种服务器编程语言都对规范进行了实现,如 gojavaphp 等,当然伟大的 javascript 也有,如不温不火的 ajv

以下是校验用户信息的一个 Schema,可见语法复杂与繁琐:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "User",
  "description": "用户信息",
  "type": "object",
  "properties": {
    "id": {
      "description": "用户 ID",
      "type": "integer"
    },
    "name": {
      "description": "用户姓名",
      "type": "string"
    },
    "email": {
      "description": "用户邮箱",
      "type": "string",
      "format": "email",
      "maxLength": 20
    },
    "mobilePhone": {
      "description": "用户手机号",
      "type": "string",
      "pattern": "^(?:(?:\+|00)86)?1[3-9]\d{9}$",
      "maxLength": 15
    }
  },
  "required": ["id", "name"]
}

对于复杂的数据类型校验,JSON Schema 内置了以下 Format,方便快捷校验

  • Dates and times
  • Email addresses
  • Hostnames
  • IP Addresses
  • Resource identifiers
  • URI template
  • JSON Pointer
  • Regular Expressions

对于不在内置 Format 中的手机号,使用 ajv.addFormat 可手动添加 Format

ajv.addFormat('mobilePhone', (str) => /^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(str));

Joi

joi 自称最强大的 JS 校验库,在 github 也斩获了一万六颗星星。相比 JSON Schema 而言,它的语法更加简洁并且功能强大。

The most powerful data validation library for JS

完成相同的校验,仅需要更少的代码,并能够完成更加强大的校验。以下仅做示例,更多示例请前往文档。

const schema = Joi.object({
  id: Joi.number().required(),
  name: Joi.number().required(),
  email: Joi.string().email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } }),
  mobilePhone: Joi.string().pattern(/^(?:(?:\+|00)86)?1[3-9]\d{9}$/),

  password: Joi.string().pattern(/^[a-zA-Z0-9]{3,30}$/),
  // 与 password 相同的校验
  repeatPassword: Joi.ref('password'),
})
  // 密码与重复密码需要同时发送
  .with('password', 'repeat_password');
  // 邮箱与手机号提供一个即可
  .xor('email', 'mobilePhone')

数据校验与路由层集成

由于数据直接从路由传递,因此 koajs 官方基于 joi 实现了一个 joi-router,前置数据校验到路由层,对前端传递来的 querybodyparams 进行校验。

joi-router 也同时基于 co-body 对前端传输的各种 content-type 进行解析及限制。如限制为 application/json

Controller 레이어는 클라이언트 데이터와 상호작용하는 서버의 최상위 레이어이므로 Fail Fast 원칙을 준수하며 데이터 필터링 기능을 담당합니다. . 불법의 경우 문신 Qin Qiong 및 Yuchi Gong만큼 장엄한 데이터가 직접 반환되었습니다.

데이터 검증은 또한 반문서화된 부산물을 생성하므로 전송할 필드와 해당 형식이 무엇인지 알아보려면 데이터 검증 레이어만 살펴보면 됩니다.

다음은 일반적인 데이터 확인 방법입니다. 이 문서에서는 이를 확인하는 방법을 설명합니다.

  1. 필수/선택 사항
  2. 숫자, 문자열, 타임스탬프 및 value need to match
  3. IP, 휴대폰 번호, 이메일, 도메인 이름 등 복잡한 데이터 검증
const router = require('koa-joi-router');
const public = router();

public.route({
  method: 'post',
  path: '/signup',
  validate: {
    header: joiObject,
    query: joiObject,
    params: joiObject,
    body: joiObject,
    maxBody: '64kb',
    output: { '400-600': { body: joiObject } },
    type: 'json',
    failure: 400,
    continueOnError: false
  },
  pre: async (ctx, next) => {
    await checkAuth(ctx);
    return next();
  },
  handler: async (ctx) => {
    await createUser(ctx.request.body);
    ctx.status = 201;
  },
});
저자는 아무런 작업 없이 백엔드 프로젝트에 접하게 되었습니다. 데이터 확인 레이어인 if/else는 다양한 수준으로 넘쳐나는데, 이는 매우 고통스럽고 몇 분 안에 리팩토링해야 합니다. 🎜

JSON Schema🎜🎜JSON Schema는 JSON 기반의 데이터 확인 형식이며 json-schema.org🎜, 현재 최신 버전(2020-08)은 7.0입니다. go, java, php 등과 같은 다양한 서버 프로그래밍 언어가 사양을 구현했습니다. 물론 훌륭한 JavaScript도 있습니다. , Buwen과 같은 인기가 없습니다 ajv🎜. 🎜🎜다음은 사용자 정보를 검증하기 위한 Schema입니다. 구문이 복잡하고 번거롭다는 것을 알 수 있습니다.🎜
const safe = require('safe-regex')
const re = /(x+x+)+y/

// 能跑死 CPU 的一个正则
re.test('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')

// 使用 safe-regex 判断正则是否安全
safe(re)   // false
🎜복잡한 데이터 형식 검증을 위해 JSON Schema에는 편리하고 빠른 검증을 위해 다음과 같은 Format이 내장되어 있습니다.🎜
  • 날짜 및 시간
  • 이메일 주소
  • 호스트 이름
  • IP 주소
  • 리소스 식별자
  • URI 템플릿
  • JSON 포인터
  • 정규식
🎜휴대전화 번호가 내장된 형식이 아닌 경우 ajv.addFormat를 사용하여 Format🎜rrreee<h2 id="item-3">Joi🎜🎜<a href="https://github.com/sideway/joi" rel="nofollow noreferrer" target="_blank를 수동으로 추가하세요. ">joi🎜는 가장 강력한 JS 검증 라이브러리라고 주장하며 github에서도 별 16개를 받았습니다. JSON 스키마와 비교하면 구문이 더 간결하고 강력합니다. 🎜<blockquote>JS를 위한 가장 강력한 데이터 검증 라이브러리</blockquote>🎜동일한 검증을 완료하고, 더 적은 코드만 필요하며, 더욱 강력한 검증을 완료할 수 있습니다. 다음은 단지 예일 뿐입니다. 더 많은 예를 보려면 설명서로 이동하세요. 🎜rrreee<h2 id="item-4">데이터 검증은 라우팅 레이어와 통합됩니다🎜🎜데이터는 라우팅에서 직접 전달되므로 <code>koajsjoi <a href="https://github.com/koajs/joi-router" rel="nofollow noreferrer" target="_blank">joi-router🎜, 사전 데이터가 라우팅 계층으로 검증되고 프런트엔드 <code>쿼리로 전달된 bodyparams가 확인됩니다. 🎜🎜joi-routerco-body를 기반으로 프런트 엔드에서 전송되는 다양한 content-type을 구문 분석하고 제한합니다. application/json으로 제한하면 CSRF 공격도 어느 정도 방지할 수 있습니다. 🎜rrreee🎜정규식과 안전한 정규식🎜🎜저자는 성능 문제를 해결하면서 실제로 데이터 검증 계층에서 API가 너무 오래 걸린다는 사실을 발견했습니다. 문제의 근본 원인은 안전하지 않은 정규식에 있습니다. 그렇다면 안전하지 않은 정규식이란 무엇일까요? 🎜🎜예를 들어 CPU를 매달릴 수 있는 아래 정규식은 시한폭탄이 되어 역추적 횟수가 기하급수적으로 늘어났습니다. 🎜
可以参考文章 浅析 ReDos 原理与实践
const safe = require(&#39;safe-regex&#39;)
const re = /(x+x+)+y/

// 能跑死 CPU 的一个正则
re.test(&#39;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&#39;)

// 使用 safe-regex 判断正则是否安全
safe(re)   // false

数据校验,针对的大多是字符串校验,也会充斥着各种各样的正则表达式,保证正则表达式的安全相当紧要。safe-regex 能够发现哪些不安全的正则表达式。

总结

  1. Controller 层需要进行统一的数据校验,可以采用 JSON Schema (Node 实现 ajv) 与 Joi
  2. JSON Schema 有官方规范及各个语言的实现,但语法繁琐,可使用校验功能更为强大的 Joi
  3. 进行字符串校验时,注意不安全的正则引起的性能问题

更多编程相关知识,可访问:编程教学!!

위 내용은 Controller 계층의 Node는 어떻게 데이터 검증을 수행하나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제