백엔드 개발자(node.js)가 되는 과정

nodemailer를 활용하여 인증 이메일 보내기

soopy 2023. 7. 3. 21:09
728x90

nodemailer에 대해서 정리해보자

회원 가입 과정에서 종종 거치게 되는 이메일 검증 절차를 구현해본다.

const nodemailer = require('nodemailer');

let transporter = nodemailer.createTransport({
  // 인증 서비스는 'gmail' 사용
  service: 'gmail',
  // host를 gmail로 설정
  host: 'smtp.gmail.com',
  port: 587,
  secure: false,
  auth: {
    // gmail 주소 입력, ex) 'testmail@gmail.com'
    user: NODEMAILER_USER,
    // gmail 패스워드 입력
    pass: NODEMAILER_PASS,
  },
});

transporter 변수는 인증 메일을 발송할 메일 계정을 등록합니다.
gmail을 전송 계정으로 사용할 경우 host와 port를 SMTP(Simple Mail Transfer Protocol) 서버에 연결하기 위해서는 위와 같이 설정합니다.

// 계정 생성 과정에서 isEmailValid를 false로 데이터베이스에 저장
await Users.create({ email, name, password: passwordToCrypto, isEmailValid: false });

const url = `http://${HOST}/api/users?email=${email}`;

await transporter.sendMail({
      // 보내는 곳의 이름과, 메일 주소를 입력
      from: `"company" <${NODEMAILER_USER}>`,
      // 받는 곳의 메일 주소를 입력
      to: email,
      // 보내는 메일의 제목을 입력
      subject: '[company] 회원가입 인증 메일입니다.',
      // 보내는 메일의 내용을 입력
      // text: 일반 text로 작성된 내용
      // html: html로 작성된 내용
      html: `<form action="${url}" method="POST">
      <h2 style="margin: 20px 0">[company] 메일확인</h2>
      <button style=" background-color: #ff2e00; color:#fff; width: 80px; height:40px; border-radius: 20px; border: none;">가입확인</button>
    </form>`,
    });

보내는 계정 정보가 등록된 transporter 변수의 sendMail 메서드를 통해 계정 생성 후 생성한 계정 이메일로 인증 메일을 발송합니다.
발송할 내용은 text와 html 형태로 보내줄 수 있습니다. 현재 html 형태를 취하여 버튼을 생성하여 메일 내용으로 보내주고 있으며 인증 메일 내용으로 받은 html에서 '메일 확인' 버튼을 클릭 시 email 인증을 위한 API 경로로 이동합니다.

// 이메일 인증 처리 관련 API (버튼 클릭 시 작동)
router.post('/', async (req, res) => {
  try {
    const { email } = req.query;
    if (!email) return res.status(412).render('authResult', { message: '비정상적인 접근입니다.???' });

    const emailValid = await Users.findOne({ where: { email: email }, attributes: ['email', 'isEmailValid'] });

    if (!emailValid) return res.status(412).render('authResult', { message: '해당 이메일은 요청된 이메일이 아닙니다.' });
    if (emailValid.isEmailValid) return res.status(412).render('authResult', { message: '이미 인증된 이메일 입니다.' });

    await Users.update({ isEmailValid: true }, { where: { email: email } });

    return res.status(201).render('authResult', { message: '인증이 완료되었습니다.' });
  } catch (err) {
    console.error(err);
    return res.status(400).render('authResult', { message: '오류가 발생하였습니다.' });
  }
});

받은 인증 메일에서 가입 확인 버튼 클릭 시 위 API가 작동하고, 해당 메일주소가 데이터베이스에 존재하는지 확인하여 isEmailValid 프로퍼티를 true로 변환합니다. 이를 통해 isEmailValid가 false일 경우 로그인이 불가하도록 조치하는 방식으로 해당 계정이 이메일 검증 완료를 했는지 확인합니다.

728x90
728x90