티스토리 뷰

노드메일러란?

■ Node.js 애플리케이션을 위한 모듈로, 노드환경에서 쉽게 이메일을 보낼수 있게 해준다.

■ 대부분의 Node.js사용자가 기본적으로 사용하는 솔루션

■ EmailEngine에 등록된 이메일 계정을 사용하여 이메일을 수신하고 이메일을 보낼 수 있다.

노드메일러 공식 홈페이지

 

일단 네이버로 인증메일을 보낼것이기 때문에 네이버의 SMTP 서버를 허용해주어야 한다.

 

SMPT서버 허용하기

네이버 메일의 아래 환경설정을 누르면 해당 페이지로 이동한다.

 

위와 같은 설정을 해준뒤 저장을 눌러준다.

 

여기에서 SMTP서버명과 포트번호를 기억한다.

 

 

SMTP서버 환결 설정 하기

// config.js

import nodemailer from 'nodemailer';
import dotenv from 'dotenv';
dotenv.config();

// 전송객체 생성, 옵션객체를 전달하여 전송객체를 설정
export const smtpTransport = nodemailer.createTransport({
    pool: true, // SMTP풀 사용여부, 여러 이메일을 보낼때 연결을 재 사용할수 있도록 해줌
    maxConnections: 1, // pool에서 허용되는 최대 동시 연결수를 설정
    service: process.env.MAILSERVICE, // 이메일서비스 - 어디쪽의 이메일을 사용할것인지(naver, gmail ...)
    host: process.env.HOSTMAIL, // SMTP호스트 주소(SMTP서버명)
    port: process.env.MAILPORT, // SMTP포트 번호
    secure: false, // 보안 연결(SSL,TLS)사용 여부 나타냄, 여기선 비보안 연결 사용
    requireTLS: true, // TLS(전송 계층 보안)의 필요여부,
    auth: {
        // 이메일 서버에 대한 인증정보가 포함된 객체
        user: process.env.AUTHUSER, // 이메일을 보내는 본인 이메일 (발신자)
        pass: process.env.AUTHPASS, // 해당 이메일의 비밀번호(발신자)
    },
    tls: {
        // TLS의 설정을 나타내는 객체
        rejectUnauthorized: false, // TLS 인증서의 유효성을 검사할지 여부
    },
});

 

인증문자열 생성하기

    const authCode = Math.random().toString(36).substring(2, 8); // 무작위 인증코드 생성
    const hashedCode = await bcrypt.hash(authCode, 10); // 무작위 인증코드 해시하기

 

인증문자 표시 html과 메일 옵션

        const checkMail = (data) => {
            return `
                  <!DOCTYPE html>
                  <html lang="en">
                  <head>
                      <meta charset="UTF-8">
                      <meta name="viewport" content="width=device-width, initial-scale=1.0">
                      <title>이메일 인증</title>
                  </head>
                  <body>
                      <div> 인증문자는 ${data} 입니다. </div>
                  </body>
                  </html>
                  `;
        };

        const mailOptions = {
            from: process.env.AUTHUSER, //발신자 이메일
            to: email, // 사용자가 입력한 이메일 == 인증할 이메일
            subject: '인증메일입니다.', // 메일제목
            html: checkMail(authCode), //표현할 html
        };

        return { mailOptions, hashedCode };

 

이메일 보내기

    // 이메일 인증보내기
    mailSend = async (req, res, next) => {
        try {
            const { email } = req.body;

            if (!email) {
                return res.status(404).json({ errMessage: '이메일이 존재하지 않습니다.' });
            }

            const emailAuthInfo = await this.usersService.emailAuth(email);

            smtpTransport.sendMail(emailAuthInfo.mailOptions, (err, response) => {
                console.log('response', response);
                if (err) {
                    smtpTransport.close(); //전송종료
                    return res.status(550).json({ errorMessage: '메일 전송에 실패하였습니다.' });
                } else {
                    smtpTransport.close(); //전송종료
                }
            });
            res.cookie('authCode', emailAuthInfo.hashedCode, { maxAge: 3600000 });
            return res.status(200).json({ successMessage: '인증 메일이 발송되었습니다.' });
        } catch (err) {
            next(err);
        }
    };

해당 함수가 호출되면 서비스를 통해 설정된 값들에 따라 움직이고 메일이 보내진다.

 


여기부터 추후 리팩토링해가면서 고쳐야 할것.

 

위쪽에 인증메일 발송하기전 쿠키를 통해 해쉬코드를 authCode라는 키값과 함께 보내고 있다.

회원가입 할 때 사용하기 위함인데 이건 보안에 큰위험이 있다.

또한 

// 이메일 인증하기
mailCheck = async (req, res, next) => {
        try {
            const { authCode } = req.body;

            if (!authCode) {
                return res.status(401).json({ errMessage: '인증 번호를 입력해주세요.' });
            }

            if (!(await bcrypt.compare(authCode, req.cookies.authCode))) {
                return res.status(401).json({ success: false, message: '인증번호가 일치하지 않습니다.' });
            }

            res.clearCookie('authCode');
            res.cookie('isEmailAuth', 'true');

            return res.status(200).json({ successMessage: '이메일 인증이 완료되었습니다.' });
        } catch (err) {
            next(err);
        }
    };

메일을 체크하는 부분에서도 인증할 때 적는 인증번호와 쿠키에서 가져온 코드로 비교를 하며

이메일 인증이 되었는지 확인하는 부분도 쿠키를 통해 전달되고 있다.

이부분은 보안에 정말 안좋은것 같다고 생각을 한다.

이렇게 되면 회원가입 부분도 이메일인증이 되는지 쿠키에 있는 값을 통해서 확인을 하게 될텐데

회원가입과 이메일 인증과 같은 보안과 밀접한 부분을 쿠키를통해서 인증을한다는건 옳지 않다.

그래서 추후에는 레디스를 적용시켜서 인증하는 부분을 보다 안정성있게 구현할 생각이다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함