[BACK-005][기초] 입력을 검증하고 이해하기 쉬운 오류 보내기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[BACK-005][기초] 입력을 검증하고 이해하기 쉬운 오류 보내기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 229회 작성일 26-09-01 01:37

본문

[이번 수업]
API가 받은 값을 어디서, 어떤 순서로 검사하고 실패를 어떻게 알려 주는지 배웁니다. JSON 문법 오류에는 400, 값 규칙 오류에는 422를 반환하는 예제를 만듭니다.

[선수지식]
JSON, HTTP 요청·응답, 상태 코드를 알고 Node가 설치되어 있으면 됩니다.

[학습목표]
1. 문법 검증과 의미 검증을 구분한다.
2. 자료형·길이·범위·허용값을 서버에서 검사한다.
3. 클라이언트가 처리하기 쉬운 오류 응답을 설계한다.

[핵심개념]
검증은 JSON 문법, 객체 모양과 자료형, 길이·범위·허용값, 업무 규칙 순으로 진행합니다. 차단 목록보다 허용 형식과 범위를 명시하는 허용 목록이 기본입니다. 브라우저 검증은 우회할 수 있으므로 서버가 최종 검사합니다.

RFC 9110의 400 Bad Request는 잘못된 요청 문법 같은 클라이언트 오류, 422 Unprocessable Content는 문법은 맞지만 담긴 지시를 처리할 수 없는 경우입니다. API 규칙을 문서화하고 일관되게 적용하세요.

RFC 9457의 Problem Details는 type, title, status, detail, instance로 오류를 표현합니다. errors는 필드별 문제를 위한 확장 필드입니다. HTTP 상태와 본문 status를 맞추세요.

[따라하기]
validate-demo.js를 만들고 다음 코드를 붙여 넣습니다.

```js
function problem(status, title, errors) {
  const body = { type: "about:blank", title, status };
  if (errors) body.errors = errors;
  return { status, body };
}

function handle(raw) {
  let input;
  try { input = JSON.parse(raw); }
  catch { return problem(400, "잘못된 JSON입니다."); }

  const errors = {};
  const name = typeof input?.name === "string" ? input.name.trim() : "";
  if (name.length < 2 || name.length > 20)
    errors.name = "이름은 2~20자여야 합니다.";
  if (!Number.isInteger(input?.age) || input.age < 0 || input.age > 150)
    errors.age = "나이는 0~150 사이 정수여야 합니다.";

  if (Object.keys(errors).length)
    return problem(422, "입력값을 처리할 수 없습니다.", errors);
  return { status: 201, body: { name, age: input.age } };
}

for (const raw of ['{"name":', '{"name":"A","age":-1}',
                  '{"name":"하늘","age":20}']) {
  const response = handle(raw);
  console.log(response.status, JSON.stringify(response.body));
}
```

터미널에서 `node validate-demo.js`를 실행합니다. 예상 상태는 차례로 400, 422, 201이며 두 번째 결과에는 name과 age 오류가 함께 표시됩니다. Windows·macOS·Linux 모두 명령이 같습니다.

[흔한 실수]
숫자 문자열을 자동 변환하지 말고 자료형을 명시하세요. 첫 오류만 또는 모든 오류를 반환할지 통일합니다. 검증 뒤에도 출력 인코딩과 매개변수화된 질의가 필요합니다.

[보안 주의]
본문 크기, 배열 수, 중첩 깊이에 상한을 둡니다. 예상 밖 필드는 정책에 따라 거부하거나 버립니다. 오류 응답에는 스택 추적, 파일 경로, SQL, 비밀값을 넣지 말고 추적용 식별자만 돌려준 뒤 상세 내용은 서버 로그에 안전하게 남깁니다. 입력 검증은 인증·권한 검사나 SQL 삽입 방어를 대신하지 않습니다. 실습은 본인 소유의 로컬 환경에서만 진행합니다.

[직접 해볼 과제]
1. email 필드를 추가해 문자열 여부와 5~100자 길이를 검사하세요.
2. 허용하지 않은 role 값이 들어오면 errors.role을 반환하고, 유효한 입력은 201이 되는 테스트를 추가하세요.

[확인문제]
1. 브라우저 검증만으로 충분하지 않은 이유는 무엇인가요?
2. JSON 문법 오류와 값 범위 오류는 예제에서 각각 어떤 상태를 반환하나요?
3. 오류 응답에 스택 추적을 담으면 안 되는 이유는 무엇인가요?

[다음 학습]
BACK-006에서 쿠키·세션·토큰의 차이와 로그인 흐름을 이어서 배웁니다.

[공식 참고 자료]
RFC 9110 400 Bad Request: https://www.rfc-editor.org/rfc/rfc9110.html#name-400-bad-request
RFC 9110 422 Unprocessable Content: https://www.rfc-editor.org/rfc/rfc9110.html#name-422-unprocessable-content
RFC 9457 Problem Details for HTTP APIs: https://www.rfc-editor.org/rfc/rfc9457.html
OWASP Input Validation Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
1,414
어제
5,103
최대
16,772
전체
772,468
Copyright © 소유하신 도메인. All rights reserved.