본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.
팀원들이 각자 맡은 부분을 API 기능별로 테스트 진행함
API 테스트를 통해서 유효성 검사나 오타로 인한 에러들을 해결함
대부분의 에러가 그저 오타로 인한 문제라서 따로 기록하기 어려움
그리고 아직 Controller - Service - Repository의 흐름을 이해하지 못한 팀원들이 각 계층의 메서드의 매개변수를 잘 못 적는 경우도 많이 발생했음
팀원분 중 Refresh Token 인증 미들웨어에서 에러를 해결하지 못한 케이스가 발생했음
결국 문제는 해결하지 못했지만, 해결 과정 중 bcrypt.compare()의 로직에 대해 알지 못했던 내용이 있어서 정리하려고 함
일단, 기존에 알고 있던 bcrypt.compare(token, hashedToken)의 로직은 bcrypt.compare가 입력받은 token을 해싱해서 이미 해싱된 hashedToken과 비교해서 같은지 확인하는 메서드라고 알고 있었음
근데 문득 compare() 메서드 안에서도 해싱이 이뤄지고 있다면 이게 분명 시간이 달라서 값이 다를 텐데 어떻게 같다고 비교할 수 있을까 라고 생각했음
그래서 찾아보니 입력받은 token을 그냥 해싱하는 게 아니었음
bcrypt.compare()의 로직은 다음과 같음
즉, 그냥 일반적인 해싱을 하는 게 아니라 해싱된 데이터에서 솔트를 추출해서 동일하게 해싱하는 것임
API 명세서 완성하기
리드미 완성하기
API 테스트 사진 첨부하기
내일이 발표하는 날이기 때문에 구현한 내용들을 마무리하고 테스트를 진행했음
테스트를 진행하니 생각보다 메서드와 매개변수의 오타로 인해 발생하는 오류가 많았음
그래서 팀원들에게 메서드와 매개변수를 작성할 때의 주의할 점을 설명했음
사용자에게 입력을 받을 때 입력값의 유효성을 검사하는 Joi 미들웨어를 구현했음
구현이 끝나고 테스트하는 과정에서 원래는 정수가 들어가 자리에 문자열로 숫자를 넣으면 Joi에서 에러를 필터링하지 못하는 문제가 발생했음
원래는 문자열 자체를 걸러야 하는 데 그냥 통과해 버리는 문제임
찾아보니 나와 똑같은 문제가 발생한 글을 찾았음
기존에 작성한 코드는 다음과 같음
import Joi from 'joi';
import { HTTP_STATUS } from '../../constants/http-status.constant.js';
import { RESERVATION_MESSAGES } from '../../constants/reservation.message.constant.js';
const createReservationSchema = Joi.object({
petsitterId: Joi.number().required().messages({
'number.base': RESERVATION_MESSAGES.RESERVATION.COMMON.PETSITTER_ID.BASE,
'any.required': RESERVATION_MESSAGES.RESERVATION.COMMON.PETSITTER_ID.REQUIRED,
}),
...
hour: Joi.number().required().messages({
'number.base': RESERVATION_MESSAGES.RESERVATION.COMMON.HOUR.BASE,
'any.required': RESERVATION_MESSAGES.RESERVATION.COMMON.HOUR.REQUIRED,
}),
etc: Joi.string().messages({
'string.base': RESERVATION_MESSAGES.RESERVATION.COMMON.ETC.BASE,
}),
});
export const createReservationValidator = async (req, res, next) => {
try {
await createReservationSchema.validateAsync(req.body);
next();
} catch (error) {
return res.status(HTTP_STATUS.BAD_REQUEST).json({
status: HTTP_STATUS.BAD_REQUEST,
message: error.details[0].message,
});
}
};
아래와 같이 그냥 통과해버리고 서버에서 오류가 발생했음
찾아보니 일반적으로 number()를 사용하면 그냥 문자열 숫자도 정수로 인식해서 통과한다고 함
그래서 사용한 방법은 아래와 같이 Joi에 새로운 옵션을 사용했음
import Joi from 'joi';
import { HTTP_STATUS } from '../../constants/http-status.constant.js';
import { RESERVATION_MESSAGES } from '../../constants/reservation.message.constant.js';
const createReservationSchema = Joi.object({
petsitterId: Joi.number()..integer().options({ convert: false }).required().messages({
'number.base': RESERVATION_MESSAGES.RESERVATION.COMMON.PETSITTER_ID.BASE,
'any.required': RESERVATION_MESSAGES.RESERVATION.COMMON.PETSITTER_ID.REQUIRED,
}),
...
hour: Joi.number()..integer().options({ convert: false }).required().messages({
'number.base': RESERVATION_MESSAGES.RESERVATION.COMMON.HOUR.BASE,
'any.required': RESERVATION_MESSAGES.RESERVATION.COMMON.HOUR.REQUIRED,
}),
etc: Joi.string().messages({
'string.base': RESERVATION_MESSAGES.RESERVATION.COMMON.ETC.BASE,
}),
});
export const createReservationValidator = async (req, res, next) => {
try {
await createReservationSchema.validateAsync(req.body);
next();
} catch (error) {
return res.status(HTTP_STATUS.BAD_REQUEST).json({
status: HTTP_STATUS.BAD_REQUEST,
message: error.details[0].message,
});
}
};