#1. 메일보내기

1. SMTP, POP3

1) SMTP

  • 간이 전자 우편 전송 프로토콜(Simple Mail Transfer Protocol, SMTP)의 약자로 인터넷에서 이메일을 보내기 위해 사용되는 프로토콜이다. (메일 발송 목적)
  • 웹 서버는 자체적으로 메일 발송을 할 수 없기 때문에 발송을 원하는 경우 SMTP 서버와 연동해야한다.

 

2) POP3

  • Post Office Protocol의 약자로 자신에게 온 메일은 POP3 서버에 저장되며, 이것은 메일 프로그램을 통해 자신의 컴퓨터로 받아와 볼 수 있다. (메일 수신 목적)
  • 양방향 동기화를 사용하는 최신 프로토콜과 달리 POP3는 일방향 전자 메일 동기화만 지원한다.
    • 따라서 사용자는 서버에서 클라이언트로 전자 메일을 다운로드 하는 것만 허용된다.

 

※ SMTP와 POP3는 외부에 노출이 잘 되기 떄문에 조금만 잘 못 세팅해도 스팸 발송 서버로 약용되는 경우가 많다.

 

2. Node.js로 메일 보내기

메일을 보내기 위한 방법은 많지만, 구글을 통해서 진행한다.

1) 구글 앱 비밀번호 발급받기

1. 크롬의 오른쪽 상단을 통해 Goole 계정 관리 페이지로 들어간다.

 

2. 보안 카테고리에 들어가서 2단계 인증으로 들어간다.

휴대전화로 로그인이 사용안함이면 먼저 사용으로 전환해야한다. (절차에 따라 수행)

 

3. 2단계 인증 수행 (휴대전화로 로그인)

시작하기를 누른다
절차에 따라 진행, 문자 메시지로 설정하고 보내기 하면 인증번호가 문자로 온다
인증번호 입력 후 사용설정 (절차에 따라 진행)

 

4. 2단계 인증 수행 (앱 비밀번호)

2단계 인증이 활성화 되면 앱 비밀번호로 들어간다
기타 선택
원하는 내용을 작성 후 생성
기기용 앱 비밀번호는 한번 밖에 안나오니 캡쳐 또는 다른 곳에 적어놔야 한다. 복붙 추천

 

2) 메일 보내기

- 패키지 설치

yarn add nodemailer

 

- HTML

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            label {
                display: block;
                width: 150px;
                height: 30px;
                line-height: 40px;
            }
        </style>
    </head>
    <body>
        <form id="mail-form" method="post" action="/send_mail">
            <div>
                <label for="writer_name">발송자 이름</label>
                <input type="text" id="writer_name" name="writer_name" />
            </div>
            <div>
                <label for="writer_email">발송자 메일주소</label>
                <input type="text" id="writer_email" name="writer_email" />
            </div>
            <div>
                <label for="receiver_name">수신자 이름</label>
                <input type="text" id="receiver_name" name="receiver_name" />
            </div>
            <div>
                <label for="receiver_email">수신자 메일주소</label>
                <input type="text" id="receiver_email" name="receiver_email" />
            </div>
            <div>
                <label for="subject">메일제목</label>
                <input type="text" id="subject" name="subject" />
            </div>
            <div>
                <label for="content">내용</label>
                <textarea id="content" name="content"></textarea>
            </div>
            <div>
                <button type="submit">메일발송</button>
            </div>
        </form>

        <script src="//cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
        <script src="//cdn.ckeditor.com/ckeditor5/31.1.0/classic/ckeditor.js"></script>
        <script>
            // ckeditor 생성
            ClassicEditor.create(document.querySelector('#content'));

            // submit 이벤트 발생시
            document.getElementById('mail-form').addEventListener('submit', async (e) => {
                e.preventDefault();
                const current = e.currentTarget;

                // 백엔드에 보낼 값을 비동기 처리
                try {
                    const response = await axios.post(current.action, {
                        writer_name: document.querySelector('#writer_name').value,
                        writer_email: document.querySelector('#writer_email').value,
                        receiver_name: document.querySelector('#receiver_name').value,
                        receiver_email: document.querySelector('#receiver_email').value,
                        subject: document.querySelector('#subject').value,
                        content: document.querySelector('#content').value,
                    });
                    alert('메일 발송에 성공했습니다.');
                } catch (error) {
                    console.log(error);
                    alert('에러가 발생했습니다. 관리자에게 문의 바랍니다.');
                }
            });
        </script>
    </body>
</html>

 

- Node.js

import express from 'express';               // express 호출
import bodyParser from 'body-parser';        // POST 파라미터 처리
import serveStatic from 'serve-static';      // 특정 폴더의 파일을 URL로 노출시킴
import nodemailer from 'nodemailer';         // 메일발송 -> app.use()로 추가 설정 없음

const app = express();  // express 사용
const port = 3002;      // 포트 번호 지정

/** HTML, CSS, IMG, JS 등의 정적 파일을 URL에 노출시킬 폴더 연결 */
// "http://아이피(혹은 도메인):포트번호" 이후의 경로가 router에 등록되지 않은 경로라면 static 모듈에 연결된 폴더 안에서 해당 경로를 탐색한다.
app.use('/', serveStatic('public'));

/** POST 파라미터 수신 모듈 설정, 추가되는 미들웨어들 중 가장 먼저 설정해야한다. */
// body-parser를 이용해 application/x-www-form-urlencoded 파싱
// extended: ture -> 지속적 사용
// extended: false -> 한번만 사용
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.text());  // TEXT형식의 파라미터 수신 가능
app.use(bodyParser.json());  // JSON형식의 파라미터 수신 가능

/** res 시작 */
app.post('/send_mail', async (req, res, next) => {
  /** 1) 프론트엔드에서 전달한 사용자 입력값 */
  const writer_name = req.body.writer_name;
  let writer_email = req.body.writer_email;
  const receiver_name = req.body.receiver_name;
  let receiver_email = req.body.receiver_email;
  const subject = req.body.subject;
  const content = req.body.content;

  /** 2) 보내는 사람, 받는 사람의 메일 주소와 이름 */
  // 보내는 사람의 이름과 주소
  // -> 외부 SMTP 연동시 주의사항 :: 발신주소가 로그인 계정과 다를 경우 발송이 거부된다.
  if(writer_name) {
    // ex) 홍길동 <gildong1234@mail.com>
    writer_email = writer_name + ' <' + writer_email + '>';
  }

  // 받는 사람의 이름과 주소
  if(receiver_name) {
    receiver_email = receiver_name + ' <' + receiver_email + '>';
  }

  /** 3) 메일 발송정보 구성 */
  const send_info = {
    from: writer_email,
    to: receiver_email,
    subject: subject,
    html: content,
  };

  /** 4) 발송에 필요한 서버 정보를 사용하여 발송객체 생성 */
  const smtp = nodemailer.createTransport({
    host: 'smtp.gmail.com',     // SMTP 서버명
    port: '465',        		// SMTP 포트
    secure: true,               // 보안연결(SSL) 필요
    auth: {
      user: 'Gamil 로그인에 사용하는 메일주소', 
      pass: '구글에서 발급받은 앱 비밀번호', 
    }
  });

  /** 5) 메일발송 요청 */
  let rt = 200;
  let rtMsg = 'success';

  try {
    await smtp.sendMail(send_info);
  } catch (e) {
    rt = 500;
    rtMsg = e.message;
  }

  res.status(rt).send(rtMsg);
});

app.listen(port, () => {
  console.log('-----------------------------------');
  console.log('|       Start Express Server      |');
  console.log('-----------------------------------');
});

백엔드에 보낼 내용 입력 후 메일 발송 클릭
정상적으로 메일이 발송된 모습
네이버 메일에서 확인

'국비수업 > Node.js' 카테고리의 다른 글

[Node.js] SingleTon 패턴  (0) 2022.07.06
[Node.js/express] File Upload  (0) 2022.07.04
[Node.js/express] Cookie / Session  (0) 2022.06.30
[Node.js] Express  (0) 2022.06.29
[Node.js] HTTP Server  (0) 2022.06.28

+ Recent posts