NestJS 이메일 보내기

권태형·2023년 6월 9일
1

NestJS 연습

목록 보기
18/19
post-thumbnail

node.JS에서 이메일 인증을 위해 이메일을 보내는 방법에 대해서 찾아보면 nodeMailer라이브러리를 사용하여 이메일을 보내는 포스팅을 많이 확인할 수 있다.

NestJs또한 node.js프레임워크이기 때문에 nodeMailer를 직접 사용하여도 된다. 구글검색으로 찾아본 메일전송 방법에서 NestJs는 MailerModule을 이용하는 방법이 있음을 확인했다.

따라서 공식문서에 MailerModule에 대한 사용방법을 찾아보려고 공식문서를 여기저기 뒤졌지만, 전혀 찾아볼 수 없었다. 이는 MailerModule이 NestJS공식으로 개발된 Module이 아니라 NestJS에서 사용할 수 있게끔 누군가 라이브러리화 한 모듈인 것이다.

MailerModule공식페이지를 참고하면 nestjs-modules/mailer라이브러리를 설치하고 진행할 수 있다.

설치 목록에서 봤듯이 이 모듈은 nodemailer라이브러리를 기반으로 동작하는 것 같다.

템플릿을 쉽게 사용하려면 위와같은 다른 라이브러리도 설치하라는 문구도 있지만, 이는 메일을 보낼 내용에 html템플릿을 쉽게 적용하기 위한 라이브러리이고, 나는 단순한 text만 전달할 것이기 때문에 설치 진행하지 않았다.

//app.module.ts
import { Module } from '@nestjs/common';
import { MailerModule } from '@nestjs-modules/mailer';
import { PugAdapter } from '@nestjs-modules/mailer/dist/adapters/pug.adapter';

@Module({
  imports: [
    MailerModule.forRootAsync({
      useFactory: () => ({
        transport: 'smtps://user@domain.com:pass@smtp.domain.com',
        defaults: {
          from: '"nest-modules" <modules@nestjs.com>',
        },
        template: {
          dir: __dirname + '/templates',
          adapter: new PugAdapter(),
          options: {
            strict: true,
          },
        },
      }),
    }),
  ],
})
export class AppModule {}

비동기 동작을 하기 위해서 Async configuration쪽 내용을 참고해보았다. 중요한 부분은

transport: 'smtps://user@domain.com:pass@smtp.domain.com',
        defaults: {
          from: '"nest-modules" <modules@nestjs.com>',
        },

transport에 들어가는 smtp와 해당 smtp의 메일주소와 비밀번호, smtp서버주소
defaults의 from에 메일을 보내는이의 이름과 메일주소

🙄smtp란? Simple Mail Transfer Protocol의 약자로 전자 메일을 송신하는데 사용되는 프로토콜이다.

필자는 네이버메일을 주로 사용하기 때문에 네이버메일을 보내기 위해서 네이버smtp설정하는 방법에 대해 찾아보았다.

설정 방법자체는 간단하다.

네이버 메일로 들어가서 환경설정 > pop3/imap설정 > imap/smtp설정 > 사용함으로 바꿔주고 저장.

설정완료후 위의 코드를 참고해서 동작을 실행해 보았지만 동작하지 않았다. 공식페이지의 제일 아래에 있는 Preview Email에 있는 예시코드를 보고 코드로직을 변경했다.

MailerModule.forRootAsync({
      useFactory: () => ({
        transport: {
          host: 'smtp.naver.com',
          port: 587,
          auth: {
            user: process.env.EMAILADDRESS,
            pass: process.env.EMAILPASSWORD,
          },
        },
        defaults: {
          from: `'TaeHyeongBNB' <${process.env.EMAILADDRESS}>`,//보낸사람
        },
      }),
    }),

연결이 잘 연결되었는지 확인하기 위해 Test를 보내본다.

async sendEmailAuthentication(email: string) {
    //메일 전송 테스트
    await this.mailerService.sendMail({
      to: email, //누구에게
      subject: 'Test',//제목
      text: '테스트',//내용
    });

API를 실행해보고 메일에 가서 확인해보면 잘 도착했는지 잘 연결이 되었는지 확인할 수 있다.

자 테스트가 잘 갔으니 이제 이메일을 인증하기 위한 랜덤한 인증코드를 보내자!

UUID라이브러리를 설치하여 uuidv4().substring()으로 6자리 랜덤한 인증 코드를 만들고, 해당코드를 이메일로 전송!

//이메일 인증코드 생성
  async createEmailCode() {
    return uuidv4().substring(0, 6);
  }

  //이메일 인증코드 전송 및 DB에 저장
  async sendEmailAuthentication(email: string) {
    //인증코드 생성
    const code = await this.createEmailCode();

    //인증코드 메일 전송
    await this.mailerService.sendMail({
      to: email,
      subject: 'TaeHyeongBNB 이메일 인증코드',
      text: `TaeHyeongBNB 이메일 인증코드는

      ${code} 
      
      입니다.`,
    });

    //DB저장
    return await this.authenticationService.saveAuthenticationCode(code);
  }

다음 DB에 저장된 해당 코드와 사용자가 인증확인을 위해 전해준 코드를 비교해 주는 로직을 만들어 주면 끝!

profile
22년 12월 개발을 시작한 신입 개발자 ‘권태형’입니다. 포스팅 하나하나 내가 다시보기 위해 쓰는 것이지만, 다른 분들에게도 도움이 되었으면 좋겠습니다. 💯컬러폰트가 잘 안보이실 경우 🌙다크모드를 이용해주세요.😀 지적과 참견은 언제나 환영합니다. 많은 댓글 부탁드립니다.

0개의 댓글