* 프로그래머스, 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 5기 강의 수강 내용을 정리하는 포스팅.
* 원활한 내용 이해를 위해 수업에서 제시된 자료 이외에, 개인적으로 조사한 자료 등을 덧붙이고 있음.
사용자가 입력한 데이터가 특정 요구사항을 충족하는지 확인하는 과정.
데이터베이스에 저장되어서는 안되는 데이터 혹은 데이터베이스 탈취나 공격을 목적으로 하는 공격 목적의 데이터 입력을 사전에 차단하기 위함.
잘못된 데이터가 입력되었다면, SQL문을 실행하기 이전에 유효성 검사 단계를 통해 데이터베이스에 이상한 데이터가 들어가지 않도록 막는다. 추가로 불필요한 SQL문의 실행도 방지하여 자원 효율성도 동반 상승한다.
보안 목적에서 매우 중요. 사용자 경험 면에서 중요한 단계.
프론트엔드와 백엔드 양쪽에서 모두 실시하는 것이 보안 측면에서 가장 안전한 방식이다.
프론트엔드에서는 자바스크립트를 쉽게 제거할 수 있어 보안 측면에서는 거의 무의미하다. 다만 사용자의 UI 사용 경험을 더 좋게 만든다는 점에서 역시 중요하다.
- 입력이 잘못되었을 때, 이를 바로바로 프론트에서 표시해주는 것.
예시: 이메일이 user@example.com 형식을 따르는지 확인.
예시: 이름, 비밀번호 등 필수 입력값이 비어 있지 않은지 확인.
예시: 숫자가 1에서 100 사이인지, 문자열 길이가 8자 이상인지.
예시: 비밀번호와 비밀번호 확인 값이 동일한지 확인.
예시: 이미 등록된 이메일인지 확인.
<form>
<input type="email" name="email" required placeholder="Enter your email">
<input type="number" name="age" min="18" max="99" required placeholder="Enter your age">
<button type="submit">Submit</button>
</form>
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
const email = form.email.value;
// 유효성 검사 로직
if (!email.includes('@')) {
alert('Invalid email format');
event.preventDefault(); // 제출 중단
}
});
유효성 검사는 말은 거창하지만 구현하기가 굉장히 쉽다.
위 예시에서는 사용자가 입력한 값을 가져와서, 이메일 주소에는 반드시 포함되어야 하는 @문자가 존재하는지 확인하고. 존재하지 않는다면 경고 메시지를 출력하고 후속 작업이 동작하지 않도록 중단해주고 있다.
app.post('/submit', (req, res) => {
const { email, age } = req.body;
// 유효성 검사 로직
if (!email || !email.includes('@')) {
return res.status(400).send('Invalid email');
}
// 유효성 검사 로직
if (!age || age < 18 || age > 99) {
return res.status(400).send('Age must be between 18 and 99');
}
res.send('Validation passed');
});
@가 포함된 정상적인 이메일 주소인지 1번 확인.
그 뒤에는 입력한 나이의 값이 18 초과, 99 미만인지 확인.
이전 포스팅 참조.
무슨 이유에서 값 입력에서 문제가 발생하였는지, 사용자에게 명확하게 알려주는 것은 중요하다.
다만 해킹으로 악용될 수 있는 시스템 정보라던지, 어떤 정보를 콕 찝어서 잘못되었다고 알려주는 것은 보안 측면에서 문제가 될 수 있다.
당연하지만 유효성 검사는 직접 구현 이외에도 라이브러리를 사용할 수 있다.
express-validator. Express.js 애플리케이션에서 요청 데이터의 유효성을 검사하고 데이터를 정리하기 위한 미들웨어 라이브러리.
API 개발 과정에서 클라이언트가 보낸 요청 데이터가 유효한지 확인하고, 잘못된 데이터를 사전에 차단하기 위해 사용한다.
이메일, URL, 숫자 범위, 문자열 길이 등등.. 이외에도 본인이 원하는 검사를 만들어서 추가할 수도 있다.
const express = require('express');
const { body, validationResult } = require('express-validator');
const app = express();
app.use(express.json()); // JSON 파싱 미들웨어
app.post('/login', [
body('email').isEmail().withMessage('Invalid email format'),
body('password').isLength({ min: 6 }).withMessage('Password must be at least 6 characters long')
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
res.send('Login successful!');
});
app.listen(3000, () => console.log('Server running on port 3000'));
body('email').isEmail().withMessage('Invalid email format'),
body('password').isLength({ min: 6 }).withMessage('Password must be at least 6 characters long')
body('username').trim().notEmpty().withMessage('Username cannot be empty'),
body(field): 요청의 body에서 특정 필드를 검사.
query(field): 요청의 query string에서 필드를 검사.
param(field): 요청의 URL 파라미터에서 필드를 검사.
check(): 유연한 필드 선택(어느 위치든 가능).