본문 바로가기

백엔드/노드

[NodeJS] 이메일의 도메인이 존재하는지 확인해보자

반응형

포스트 목적

노드메일러 등의 SMTP 를 활용한 메시지 전송 패키지나 도구를 사용할 때, 이메일을 받는 이의 도메인이 존재하는지 아닌지 확인하기 위한 기능을 만들어 보았고, 이에 대한 정리를 위해 작성한다.


 

 

우선 이번 기능을 구현하기 앞서 사전 지식이 필요하다. 세부적으로 살펴본다면 DNS의 전반적인 내용을 다뤄야 하는게 맞지만, 필요한 개념만 살펴본다면 그 중 제일 중요한 MX 레코드에 대해 언급하고자 한다.

 

MX 레코드

MX 레코드는 쉽게 말해 SMTP 로 전송되는 이메일 메시지를 라우팅(경로 나누기) 하는 방법을 나타내는데 쓰인다. 그래서 해당 도메인에 대한 MX레코드를 조회 해보면, 각 라우트 가능한 서버가 우선순위에 따라 나눠서 조회되는 것을 확인할 수 있다. 

 

즉, 각 우선순위에 따라 우선순위가 가장 높은 서버로 이메일 메시지를 보내도록 할 때 사용된다.

 

NodeJS  에서 조회된 MX 레코드 정보

 

 

MX 레코드는 레코드일 뿐인데 이걸로 어떻게 도메인 유무를 판단할까?

사용자로 부터 전달받은 이메일에서 도메인에 해당하는 부분을 조회했을 때 MX 레코드가 존재하지 않는다면 사실상 해당 메일의 도메인은 존재하지 않는 곳으로 판단할 수 있다.

 

따라서 해당 원리를 기반으로 NodeJS  에서 제공하는 기능을 활용하여 도메인의 존재 유무를 판단하는 기능을 쉽게 구현할 수 있다.


 

 

구현에 앞서 NodeJS 에서 제공하는 MX 레코드를 조회하는데 사용되는 메소드를 소개하고자 한다.

dnsPromises.resolveMx(hostname)

이 내장 메소드는 hostname (ex. naver.com)  를 전달받으면 해당 hostname(도메인)이 존재하는 경우 도메인의 메일 서버를 조회한다. 그 후 조회된 메일 서버의 MX 레코드를 반환한다.

 

반면, 조회된 도메인이 존재하지 않는다면, 에러를 띄운다.

 

참고로, Promise 를 반환하므로 async ~ await 이나 then 체이닝을 활용해야 한다. 만일 callback 형태로 접근하고자 한다면, dns 모듈을 가져와서  dns.resolveMx(hostname, (err, addresses) => { }) 형태로 접근하면 된다.

 

해당 메소드에 내장 자세한 내용은 아래 공식 문서를 확인 하자

https://nodejs.org/docs/latest/api/dns.html#dnspromisesresolvemxhostname

 

DNS | Node.js v21.6.2 Documentation

DNS# Source Code: lib/dns.js The node:dns module enables name resolution. For example, use it to look up IP addresses of host names. Although named for the Domain Name System (DNS), it does not always use the DNS protocol for lookups. dns.lookup() uses the

nodejs.org

 

구현하기 | ① 모듈 불러오기

우선 해당 메소드의 모듈을 불러온다. 현재 본인이 사용하고 있는 NextJS 의 Node 환경이므로 import ~ export 를 안정적으로 지원하기 때문에 아래와 같은 형태를 취하지만, 실제 node 환경에서 사용하고 있다면  CommonJS 를 적용하면 된다.

import dnsPropmises from 'node:dns/promises' // ES 모듈
// or
const dnsPropmises = require('node:dns/promises') // CommonJS

 

 

구현하기 | ② 로직 구현하기

서두에 비해서 구현되는 코드는 단순하다. 작성된 로직은 다음과 같다. 본인의 경우 해당 로직을 다른 파일에서 재사용하기 위해 함수로 작성 하였다. 

 

export async function emailMxValidator(userEmail: string) {

    const domain = userEmail.split('@')[1] || ''
    if (!domain.includes('.')) return false
    try {
        await dnsPropmises.resolveMx(domain)
        return true
    } catch (error) {
        // console.error('도메인 조회 실패:', error)
        return false
    }
}

 

 

이메일의 도메인 추출하기

로직을 살펴보면, 우선 domain 이라는 변수에 사용자로부터 전달받은 이메일의 도메인을 추출하여 담는다.

    const domain = userEmail.split('@')[1] || ''

 

 

추출한 도메인을 resolveMx(argu) 의 인자로 넘겨주기

 

그리고 해당 domain 을  resolveMx(domain) 의 인자로 넘겨주면 된다.

dnsPropmises.resolveMx(domain)

 

 

나머지 필요에 따라 예외처리 등의 처리 수행하기

나머지는 예외처리 후 조회 실패와 성공에 대한 true/false 를 반환하게 하였고, 이를 사용하고자 하는 파일에서 불러와서 호출하면 그 결과가 비동기적으로 반환되도록 하였다.

 

export async function emailMxValidator(userEmail: string) {

    const domain = userEmail.split('@')[1] || ''
    if (!domain.includes('.')) return false
    try {
        await dnsPropmises.resolveMx(domain)
        return true
    } catch (error) {
        // console.error('도메인 조회 실패:', error)
        return false
    }
}

 

 

시연 | 구현된 기능 시연

그럼 완성된 기능이 정상적으로 동작하는지 확인해보자

 

 

실패하면 아래 에러를 띄우고

 

 

 

성공하면 MX 레코드를 반환하는 것을 확인할 수 있다.

 

 

 

 

반응형