본문 바로가기

Web Sever 개발과 CS 기초/스프링

org.passay 사용하여 @Password Validation 검증기 만들기

관련 내용

해당 프로젝트 깃허브

[백엔드/스프링] - Validation 사용하여 Respuset 정보 검증하기

개요 목적

Validation 사용하여 Respuset 정보 검증하기 글에서는 Validation에서 기본 제공해주는 애너테이션을 사용하여 검증을 실시 했다.

개발을 하다 보면 기본 제공 애너테이션은 처리가 부족하여 직접 검증 애너테이션을 만들어줄 필요가 있다.

이번 시간에는 커스텀 애너테이션과 org.pssay 라이브러리를 사용하여 비밀번호(최소 8자리 이상, 1개의 이상의 소문자, 대문자, 숫자, 특수문자가 포함되어야 한다)를 검증하는 validation을 직접 만들어보자.

@Password 검증 애너테이션 만들기

애너테이션 생성

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordConstraintsValidator.class)
public @interface Password {

    String message() default "Invalid password";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}
  • @Target(FIELD): 해당 어노테이션을 필드에만 선언 가능하다.
  • @Retention(RUNTIME): 해당 어노테이션이 유지되는 시간으로써 런타임까지 유효하다.
  • @Constraint(validatedBy = PasswordConstraintsValidator.class): PasswordConstraintsValidator를 통해 유효성 검사를 진행한다.

Password Validator 구현체 만들기

우리가 만들 패스워드 검증기는 JSR에서 제공하는 javax.validation의 ConstraintValidator 인터페이스를 구현해서 만들어야 한다.

ConstraintValidator 인터페이스는 두가지 메소드를 제공한다.

  • initialize: Validator를 초기화하기 위한 메소드
  • isValid: 유효성을 검증하는 메소드

이제 org.passy와 ConstraintValidator 인터페이스를 사용해서 검증기 구현해보자.

public class PasswordConstraintsValidator implements ConstraintValidator<Password, String> {

    @Override
    public boolean isValid(String password, ConstraintValidatorContext constraintValidatorContext) {
        //org.passay의 PasswordValidator로 검증 형식을 만들어 준다.
        PasswordValidator passwordValidator = new PasswordValidator(
            Arrays.asList(
                //Length rule. Min 8 max 128 characters
                new LengthRule(8, 128),
                //At least one upper case letter
                new CharacterRule(EnglishCharacterData.UpperCase, 1),
                //At least one lower case letter
                new CharacterRule(EnglishCharacterData.LowerCase, 1),
                //At least one number
                new CharacterRule(EnglishCharacterData.Digit, 1),
                //At least one special characters
                new CharacterRule(EnglishCharacterData.Special, 1),
                new WhitespaceRule()
            )
        );
        //org.passay의 RuleResult를 통해 들어온 정보가 통과인 지 아닌 지 검증한다.
        //true면 검증 성공
        RuleResult result = passwordValidator.validate(new PasswordData(password));
        if (result.isValid()) {
            return true;
        }

        //fals면 검증 실패
        //constraintValidatorContext를 사용해서 검증 실패시
        //예외 메세지를 지정해준다.
        constraintValidatorContext.buildConstraintViolationWithTemplate(
                Constants.joinPasswordValidation).addConstraintViolation()
            .disableDefaultConstraintViolation();
        return false;
    }
}

적용하고 실행하기

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RequestGeneralMember {

    @Pattern(regexp = "^[a-z0-9]{8,20}$", message = Constants.joinLoginNameValidation)
    private String loginName;
    //직접 만들 검증기 붙여주기
    @Password
    private String password;
    @NotBlank(message = Constants.joinNameValidation)
    private String name;
}

password 데이터를 공백으로 넘겼더니, 예외를 발생해서 400 status code를 반환한 것을 확인할 수 있다.


Reference

https://www.tutorialspoint.com/passay/passay_quick_guide.htm

https://mangkyu.tistory.com/206