@Email
은 jakarta.validation.constraints
패키지에 속한 어노테이션으로 요청 데이터가 이메일 형식을 준수하는 지 검증하는 데 활용될 수 있다.
하지만 @Email
어노테이션을 기본 속성으로 사용하게 되면 우리가 보편적으로 생각하는 mj3242@naver.com
와 같은 이메일 데이터 형식을 올바르게 검증할 수 없다.
@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
public @interface Email {
// ...
String regexp() default ".*";
// ...
}
@Email
어노테이션 코드를 보면 데이터를 검증하는 정규식의 기본값이 .*
로 문자열 내에 아무 문자나 하나 이상 존재하면 유효하다고 판단한다. 따라서 해당 어노테이션을 활용할 때는 무조건 regexp
의 설정을 커스텀해주어야 의도한 대로 이메일 데이터를 검사할 수 있다.
이메일에서 로컬, 도메인 부분을 동시에 검증할 수 있는 기본적인 정규식 형태는 다음과 같다.
^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$
_
), 하이픈(-
), 점(.
)은 허용된다.[a-zA-Z0-9_!#$%&’*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$
임의의 정규식을 사용하는 대신에 이메일 검증 정규식에 관해 나와있는 RFC 822의 업데이트 버전인 RFC 5322 표준의 정규식을 사용하는 것도 좋은 방법이다. 기본적으로 모든 문자를 허용하는 것을 확인할 수 있다. 다만, |
와 '
를 허용하지 않는데, 이는 잠재적 SQL Injection 발생을 방지하기 위함이다.
^[\\w!#$%&’*+/=?`{|}~^-]+(?:\\.[\\w!#$%&’*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$
최상위 도메인을 체크하는 정규식도 살펴보자. 위 정규식은 기본적으로 이메일 주소에 점이 하나만 존재하는지 검사한다. 또한 최상위 도메인이 2~6자의 길이를 가지는 지 확인한다.
OWASP(open web application security project)에서는 공개적으로 사용 가능한 정규식 패턴 라이브러리인 OWASP Regex Repository를 제공한다.
^[a-zA-Z0-9_+&*-] + (?:\\.[a-zA-Z0-9_+&*-] + )*@(?:[a-zA-Z0-9-]+\\.) + [a-zA-Z]{2, 7}
위 정규식은 대부분의 통용되는 이메일 구조를 검증할 수 있다.
Apache Commons Validator는 보편적인 검증에 필요한 대부분의 기능을 제공하는 라이브러리이다. 이 라이브러리에서 지원하는 EmailValidator
클래스를 활용하면 RFC 822 표준에 따라 이메일을 검증할 수 있다. 유니 코드 문자들에 대해서도 검증을 제공한다.
implementation 'commons-validator:commons-validator:1.7'
@Test
public void testUsingEmailValidator() {
emailAddress = "username@domain.com";
assertTrue(EmailValidator.getInstance()
.isValid(emailAddress));
}