Validation - Password,passay

마자나다·2024년 2월 8일

Spring

목록 보기
8/9

Password

앞서 정리한 @Valid에서 @Password라는 어노테이션이 있었다. 이는 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(ElementType.FIELD) : 어노테이션이 어느 요소에 적용될지 지정한다. FIELD로 되어있으므로 필드에만 적용되는 어노테이션이다.
  • @Retention(RetentionPolicy.RUNTIME) : 어노테이션이 유지되는 기간을 지정한다. RUNTIME에 이 어노테이션 정보를 사용할 수 있다.
  • @Constraint(validatedBy = PasswordConstraintsValidator.class) : 이 어노테이션을 처리할 실제 검증 로직을 제공하는 클래스를 지정한다.

  • message 메소드 : 유효성 검사가 실패할 경우 반환할 기본 메세지이다.
  • group 메소드 : 유효성 검사를 그룹화 할 수 있다. 기본값은 빈 배열이다.
  • payload 메소드 : 다양한 유형의 유효성 검사 페이로드를 지정할 수 있다.

PasswordConstraintsValidator 클래스

앞서 Constratint 어노테이션에서 말했듯 실제 검증 로직을 제공하는 클래스이다.


public class PasswordConstraintsValidator implements ConstraintValidator<Password, String> {
    @Override
    public boolean isValid(String password, ConstraintValidatorContext context) {
        PasswordValidator passwordValidator = new PasswordValidator(
                Arrays.asList(
                        //비밀번호 길이가 8~20 사이여야 한다.
                        new LengthRule(8, 20),
                        //적어도 하나의 대문자가 있어야 한다.
                        new CharacterRule(EnglishCharacterData.UpperCase, 1),
                        //적어도 하나의 소문자가 있어야 한다.
                        new CharacterRule(EnglishCharacterData.LowerCase, 1),
                        //적어도 하나의 숫자가 있어야 한다.
                        new CharacterRule(EnglishCharacterData.Digit, 1),
                        //적어도 하나의 특수문자가 있어야 한다.
                        new CharacterRule(EnglishCharacterData.Special, 1),
                        //공백문자는 허용하지 않는다.
                        new WhitespaceRule()
                )
        );
        RuleResult result = passwordValidator.validate(new PasswordData(password));
        if (result.isValid()) {
            return true;
        }else {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(String.join(",", passwordValidator.getMessages(result)))
                    .addConstraintViolation();
            return false;
        }
    }
}
  • 해당 코드는 Password 어노테이션을 처리하는 실제 검증 로직이다.
  • ConstraintValidator<Password, String>을 사용하여 실제 비밀번호 유효성을 검사한다.
  • PasswordValidator를 사용하여 비밀번호 유효성을 검사한다. org.passay 라이브러리를 사용하여 여러 규칙에 따라 검증한다.
  • 주석에서 보면 알 수 있듯 다양한 규칙을 비밀번호에 적용하였다.
  • .validate 메서드를 사용하여 검증하고 그 결과를 RuleResult객체로 받는다. -> 결과가 유효하면 true를 반환하고 그렇지 않다면 ConstraintValidatorContext를 사용하여 유효성 검사 실패를 나타내는 커스템 메세지를 설정한다.

ConstraintValidator

  • ConstraintValidator는 Java에서 제약조건을 검증하는 인터페이스이다. 주로 Bean Validation API에서 사용된다. 커스텀 어노테이션의 유효성 검사를 구현할떄 활용된다.

주요 기능및 메서드

  1. initialize() 메서드: 검증 프로세스를 초기화합니다. 이 메서드는 검증기가 초기화될 때 한 번 호출됩니다.
  2. isValid() 메서드: 주어진 값이 유효한지 여부를 결정합니다. 이 메서드를 구현하여 실제 유효성 검사 로직을 작성합니다.
  3. ConstraintValidatorContext: 유효성 검사 결과를 확장하고 사용자 지정 메시지를 추가하는 데 사용됩니다. 유효성 검사 실패 시 커스텀 메시지를 설정할 수 있습니다.

위와 같이 2개의 클래스를 조합하여 커스텀 어노테이션에 적용, 객체의 필드에 대한 유효성 검사를 수행할 수 있다. Passay라이브러리를 사용하여 강력한 비밀번호 검증을 수행하고, Java의 Bean Validation API를 통해 커스텀 어노테이션을 정의하여 유혀성 검사를 진행해 보았다.
profile
우왕좌왕 개발

0개의 댓글