본문 바로가기
Nodejs

[ Nodejs ] nodemailer 를 사용해서 인증코드 메일 전송하기

by teamnova 2022. 12. 27.
728x90

 

 

안녕하세요! 오늘은 nodemailer 를 사용해서 

인증코드 메일을 전송해보려고 합니다!

 

post /mail 로 요청하면 전송이 됩니다!

 

 

1.

index.js (server.js)파일에 추가하기. (필요한 모듈은 설치하셔야 합니다)


// Node.js 애플리케이션용 모듈 : 메일 전송
const nodemailer = require('nodemailer');
const senderInfo = require('../config/senderInfo.json'); //: 발송 메일 계정 정보

const express = require("express");
const http = require("http");
const app = express();
const server = http.Server(app);//.createServer(app);

const PORT = 5000;

server.listen(PORT, () => {

    console.log(`Server running on http://localhost:5000`);

    //메일 전송 예제
    app.post('/mail', (req, res) => {

        console.log("메일 발송");

        // 수신할 이메일 (통신으로 클라이언트에게서 받아와야 함.)
        const { email }  = req.body;
        console.log(req.body);
        console.log(email)

        // 인증코드 (6자리 랜덤 숫자 로 이루어진 인증코드)
        let code = create_code();
        console.log("인증코드 : "+code);

        // 인증코드 유효시간 (변경될 것 같아서 따로 변수로 변경)
        const limit_time = "3분"
        // 서비스 이름(변경될 것 같아서 따로 변수로 변경)
        const service_name = "Remember-Feedback";
        // 메일 제목
        const subject = '['+service_name+'] 회원가입 이메일 인증코드가 도착하였습니다. ';
        // 메일 내용
        const emailHtml =`<p>안녕하세요.</p>
        <p>해당 메일은 `+email+`이 정확한 이메일 주소인지 확인하는 메일입니다.</p>
        <p>`+service_name+` 인증 코드는 <strong>[`+code+`]</strong> 입니다.</p>
        <p>코드는 `+limit_time+` 후 만료됩니다.</p>`;

        // 이메일 인증을 완료하려면
        // 인증번호[158336]를
        // 입력해주세요.
        // * 개인정보 보호를 위해 이메일 인증번호는 3분간 유효합니다.
        
        let succ = function(){

          // db에 인증코드 정보 저장
          // db 연결
          //  현재 시각, 이메일 주소 저장
          // 나중에 인증코드 확인 요청이 오면 필요한 정보들을 저장한다.

          // console.log(JSON.stringfy({result:true})
          // 전송 성공 반응JSON.stringfy()
          res.status(200).send({result:true});

        }

        let fail = function(){
          // 전송 실패 반응
          console.log("전송 실패 반응")
          res.status(200).send({result:false});

        }
        // 이메일 전송 요청 (비동기 함수)
        sendGmail(service_name,email,subject,emailHtml,succ,fail)

        // 이메일 전송 요청 성공(x이메일 전송 성공은 아님x)
        
    });
    
}); 

/** 메일을 전송한다.
  * @param {string} fromServiceName 발신 서비스 이름 (undefined 시 주소만 전송됨)
  * @param {string} toEmail 수신 이메일 주소 (여러명 동시에 가능)
  * @param {string} subject 메일 제목
  * @param {string} html 메일 내용
  * @param {func} succ 메일 전송 성공시 실행되는 메소드
  * @param {func} fail 메일 전송 실패시 실행되는 메소드
  * @returns void
*/
function sendGmail(fromServiceName,toEmail,subject,html,succ,fail) {

    // 이메일을 보내려면 transport 객체가 필요하다.
    // transport 객체 생성하기
    // option : stmp 통신의 설정인 듯
    var transporter = nodemailer.createTransport({
      service: 'gmail',   // 메일 보내는 곳
      //인증 데이터를 정의
      auth: {
        user: senderInfo.user,  // 보내는 메일의 주소
        pass: senderInfo.pass   // 보내는 메일의 비밀번호
      },
      // 그 외에는 기본값으로 설정

      // //연결할 포트입니다
      // port: 587,
      // // 연결할 호스트 이름 또는 IP 주소
      // host: 'smtp.gmlail.com',  
      // // secure : true - 서버에 연결할 때 연결에서 TLS를 사용한다.
      // // secure : false (기본값 ) - 서버가 STARTTLS 확장을 지원하는 경우 TLS가 사용된다.
      // secure: false,  
      // requireTLS: true ,
      // tls: {
      // rejectUnauthorize: false,
      // },
      // maxConnections: 5,
      // maxMessages: 10,
    });


    // 서비스에서 메일을 보내지 않는다면 일반 메일 주소로 처리하기
    let mail_from;
    if(fromServiceName == undefined ){
      mail_from = senderInfo.user;
    }
    else{
      mail_from = fromServiceName+" <"+senderInfo.user+">";
    }

    // 메일 옵션
    var mailOptions = {
      from: mail_from, // 발송 메일의 주소
      to: toEmail, // 수신 이메일 주소 (수신 주소의 리스트)
      subject: subject, // 메일 제목
      html: html // 메일 내용
    };
    //amp 를 사용해봐도 좋을 듯
    
    console.log(mailOptions);

    // 메일 발송    
    // mailOptions는 메일 내용을 정의한다.
    //  function (error, info)은 선택적 콜백함수로 메세지가 전달되거나 실패하면 실행된다.
    transporter.sendMail(mailOptions, function (error, info) {
      // 메일 발송에 실패한 경우 (에러난 경우) 실행되는 콜백함수
      if (error) {
        console.log(error);
        fail()
        // return false;
      }
      // 메일 발송을 성공했을 경우??(에러나지 않은 경우) 실행되는 콜백함수?
      else {
        // info : 결과가 포함되며 정확한 형식은 사용된 전송 메커니즘에 따라 다르다.
        // info.messageld : 
        // info.envelope :
        // info.accepted : smtp 전송에서 반환된 배열?
        // info.rejected : 
        // info.pending : 
        // info.response : 
        console.log('Email sent: ' + info.response);
        // return true;
        succ()

        // 데이터베이스에 인증코드 번호를 저장한다.
        
      }
    });
}


// 인증코드 생성 
function create_code(){

    let n = Math.floor(Math.random()*1000000);
    return n.toString().padStart(6, "0");
  }

 

2. 

발신 이메일, 비밀번호를 설정하기

user에 이메일을 pass에 이메일의 비밀번호를 설정하시면 됩니다! 

저는 pass에 gmail 의 2차 비밀번호(앱) 를 설정했습니다!

 

3. 

메일 전송 요청하기

post /mail! 

 

4. 동작이 되는 것을 확인하면 원하는대로 커스텀해보기!