[TIL] 내일배움캠프 12.20

Asher Park·2022년 12월 24일
1

내일배움캠프_TIL

목록 보기
20/39
post-thumbnail

Node.js 숙련주차 과제를 시작하였다.

회원가입을 하는 API를 작성하는데 과제 요구사항을 보니

  • 닉네임은 최소 3자 이상, 알파벳 대소문자(a~z, A~Z), 숫자(0~9)로 구성하기
  • 비밀번호는 최소 4자 이상, 닉네임과 같은 값이 포함된 경우 회원가입에 실패
  • 비밀번호 확인은 비밀번호와 정확하게 일치하기

라고 유효성 검사를 하라는 것이 아닌가!

이제까지 해 오던 방식으로 하면, 입력받은 데이터들의 길이를 체크하고 정규식으로 패턴매칭을 하고
일일이 조건을 다 나누어 작성했을 것이다.

이번에는 Joi 라는 라이브러리를 적용시켜보기로 했다.
월마트 개발자들이 만들었다고 한다.
https://joi.dev/api/?v=17.7.0

설치

npm install joi

문제가 생겼다!

닉네임의 예외처리는 상당히 간단했다.

const Joi = require("joi");

const signUpSchema = Joi.object({
	nickname: Joi.string().min(3).max(30).pattern(new RegExp('^[a-zA-Z0-9]$')).required(),
});

하지만, 비밀번호에서 '닉네임과 같은 값이 포함된 경우' 라는 조건이 문제였다...

비밀번호 확인을 먼저하자! 간단하니까!

const Joi = require("joi");

const signUpSchema = Joi.object({
	nickname: Joi.string().min(3).max(30).pattern(new RegExp('^[a-zA-Z0-9]$')).required(),
  	password: Joi.string(),
  	confirm: Joi.string().valid(Joi.ref('password')).required(),
});

이제 비밀번호 유효성 검사를 해야하는데...

어? Joi.ref('nickname') 하면 입력받은 nickname 값을 가져올수 있는거 아닐까?
일단 가져오고 포함관계를 따져보자..

1. Joi.invalid()

이 함수는 안의 인자와 같지 않은지를 판별해준다. 포함의 개념이 아니었다. valid()도 그렇다.

const signUpSchema = Joi.object({
	nickname: Joi.string().min(3).max(30).pattern(new RegExp('^[a-zA-Z0-9]$')).required(),
  	password: Joi.string().invalid(Joi.ref('nickname')).required(),
  	confirm: Joi.string().valid(Joi.ref('password')).required(),
});

2. Joi.not()

위와 똑같은 동작을 하는 것 같았다.

3. Joi.pattern(new RegExp(''))

포함의 관계를 나타내어야하므로 정규식 패턴 사이에 입력받은 닉네임을 넣어보기로 했다.
나는 완벽하게 정규식을 작성했다고 생각했고 confirm에서의 논리대로 라고 하면 정상 작동 해야한다고 생각했지만,
Joi.ref('nickname')을 문자열로 보고 매칭을 시키고 있었다.
왜...?

const signUpSchema = Joi.object({
	nickname: Joi.string().min(3).max(30).pattern(new RegExp('^[a-zA-Z0-9]$')).required(),
  	password: Joi.string().min(4).pattern(new RegExp('^((?!' + Joi.ref('nickname') + ').)*$')).required(),
  	confirm: Joi.string().valid(Joi.ref('password')).required(),
});

해결

결국 튜터님의 도움을 받았다!

저 자리에 입력받은 닉네임을 넣어주기 위해 함수로 한번 감싸서
인자로 입력받은 닉네임을 넣고, Joi.object({}) 를 return 해주기로 했다.

const getSignUpSchema = function (inputNickname) {
	return Joi.object({
    	nickname: Joi.string()
            .min(3)
            .max(30)
            .pattern(new RegExp('[a-z|A-Z|0-9]$'))
            .required(),
        password: Joi.string()
            .min(4)
            .pattern(new RegExp("^((?!" + inputNickname + ").)*$"))
            .required(),
        confirm: Joi.string().valid(Joi.ref('password')).required(),
    })
}
router.post("/signup", async (req, res, next) => {
	try {
      const {nickname, password, confirm} = await getSignUpSchema(req.body.nickname).validateAsync(req.body);
      //      
    } catch (err) {
    	next(err);
    }
})

하나라도 매칭이 안되는 곳이 있다면 Error가 넘어간다.
매칭이 성공적으로 완료되면 객체구조 분해 할당으로 각각의 값들이 할당된다.


음... 분명히 Joi 에도 Contains 같은 역할을 하는 함수가 있지않을까? 존재하지않을까..?
라이브러리를 만든사람이 그걸 생각 못하진 않았을거 같은데...

+ allow 라는 함수도 있는 것 같은데 다음에 한번 테스트 해봐야겠다.

profile
배움에는 끝이없다

1개의 댓글

comment-user-thumbnail
2022년 12월 24일

재미라는 단어를 잘 모르시는 것 같습니다.......

답글 달기