01. 개요
1차 프로젝트에서는 request로 들어오는 데이터를 '@sindresorhus/is' 라이브러리를 사용해서 req.body가 비어있는지 여부만 확인했다. 하지만 좀 더 강하게 validation을 하려면 타입이 맞게 들어왔는지, 올바른 칼럼이 들어왔는지 등을 확인해야 한다. 그래서 이번엔 Joi를 사용해서 Validation 해보려 한다.
✔️ 1차 프로젝트 GitHub Repository
02. Joi 라이브러리 코드 구현
외부에서 들어오는 입력을 항상 validation 하는 습관은 중요하다고 한다.
Joi에 대한 자료가 많지 않아 문서를 참고해서 구현해보자.
현재 라우터, 서비스 로직, 디비, 미들웨어를 분리해서 작성하고 있다.
라우터 부분에 코드를 추가하는 것보단 미들웨어로 validation코드를 분리하는게 좋을 거 같아 미들웨어로 코드를 구현했다!
1) 라이브러리 설치
우리 프로젝트는 yarn 을 쓰고 있음으로 두 번째 코드로 설치했다.
(npm과 yarn 둘 중 하나의 manager만 사용하는 것을 권장한다.
npm install joi
yarn add joi
2) validation 미들웨어
Joi로 Validation 하는 부분은 미들웨어에서 함수 형태로 구현했다. 이때 올바른 형태이면 next()로 다음 회원가입이나 로그인 코드가 실행되도록 구현했다.
현재는 로그인, 회원가입 부분의 Validation을 구현했다.
const loginValidation = async (req, res, next) => {
const body = req.body;
const schema = Joi.object({
email: Joi.string().email(),
password: Joi.string().min(4).required(),
});
try {
await schema.validateAsync(body);
} catch (error) {
res.status(400).json({ code: 400, message: error.message });
}
next();
};
const registerValidation = async (req, res, next) => {
const body = req.body;
const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(4).required(),
name: Joi.string().min(2).required(),
});
try {
await schema.validateAsync(body);
} catch (error) {
res.status(400).json({ code: 400, message: error.message });
}
next();
};
[ Issue ]
처음에는 이메일을 정규표현식으로 패턴이 맞는지 검사를 해주었는데 계속 패턴이 틀리다는 오류를 받았다.
email: Joi.string()
.pattern(
new RegExp(
'/^(([^<>()[]\\.,;:s@"]+(.[^<>()[]\\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/'
)
)
.required()
팀원 분과 여러 의견을 주고받다가 공식 문서의 이 부분을 통해서 해결할 수 있었다.
같이 스터디 하는 분의 팀명이기도 한데 ' 어? 이게 되네?? ' 한 순간이었다. ㅎㅎ.. ❤️
3) validation 라우터에 적용
로그인 라우터
loginRouter.post("/login", loginValidation, async (req, res, next) => {
try {
const { email, password } = req.body;
const discoveredUser = await LoginService.findUser({ email, password });
res.status(200).json(discoveredUser);
} catch (error) {
next(error);
}
});
회원가입 라우터
registerRouter.post("/register", registerValidation, async (req, res, next) => {
try {
const { email, password, name } = req.body;
const newUser = await RegisterService.addUser({ email, password, name });
if (newUser.errorMessage) {
throw new Error(newUser.errorMessage);
}
res.status(200).json(newUser);
} catch (error) {
next(error);
}
});
📌 Reference
'프로젝트 개발 기록 > [개발] node.js | nest, express' 카테고리의 다른 글
[#1] TypeScript + Express에서 Sequelize 시작하기 (0) | 2022.06.14 |
---|---|
TypeScript + Node.js + Express 에서 프로젝트 시작하기 (0) | 2022.06.06 |
[Node.js] mongoose에서 새로운 필드 추가하기 (0) | 2022.05.01 |
[Node.js+Express] Refresh Token 구현 (0) | 2022.04.25 |
댓글