👻사용하게된 이유
"trello"와 같은 협업 웹 사이트를 만들던 중 할일을 만들 수 있는 Board 테이블에 Board 테이블 생성자가 멤버들을 초대할 수 있는 구조를 만들었다. 초대를 어떻게 구현할까 고민하다가 Board 생성자가 초대할 멤버의 메일을 적으면 그 멤버의 메일로 인증코드가 가고, 코드 입력 시 인증이 성공하며 초대받은 멤버가 Board 를 볼 수 있고, 사용할 수 있는 구조를 만들게 되었다. 이 때문에 nodemailer를 접하게 되었다.
👻사용방법
nodemailer 공식 홈페이지 / Youtube
사실 nodemailer 공식 홈페이지에 가면 예시와 함께 사용법을 자세하게 알 수 있다.
추가적으로 참고한 유튜브는 다음과 같다.
https://www.youtube.com/watch?v=JgcDZl8eXTg&t=5s
https://www.youtube.com/watch?v=ezReImKeq2U&t=1031s
이 블로그에서는 nodemailer 사용법을 조금 더 간단하게 설명해보려고 한다.
공식 문서에 보면 메인 페이지에 다음과 같은 예시 코드가 있다.
"use strict";
const nodemailer = require("nodemailer");
const transporter = nodemailer.createTransport({
host: "smtp.forwardemail.net",
port: 465,
secure: true,
auth: {
// TODO: replace `user` and `pass` values from <https://forwardemail.net>
user: "REPLACE-WITH-YOUR-ALIAS@YOURDOMAIN.COM",
pass: "REPLACE-WITH-YOUR-GENERATED-PASSWORD",
},
});
// async..await is not allowed in global scope, must use a wrapper
async function main() {
// send mail with defined transport object
const info = await transporter.sendMail({
from: '"Fred Foo 👻" <foo@example.com>', // sender address
to: "bar@example.com, baz@example.com", // list of receivers
subject: "Hello ✔", // Subject line
text: "Hello world?", // plain text body
html: "<b>Hello world?</b>", // html body
});
console.log("Message sent: %s", info.messageId);
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
//
// NOTE: You can go to https://forwardemail.net/my-account/emails to see your email delivery status and preview
// Or you can use the "preview-email" npm package to preview emails locally in browsers and iOS Simulator
// <https://github.com/forwardemail/preview-email>
//
}
main().catch(console.error);
놀랍게도, 이게 전부다.
크게 두 단계로 나누어지며, 하나는 보내는 사람의 정보를 nodemailer.createTransport로 생성하는 것이고 다른 하나는 생성된 정보를 바탕으로 메일 수신자를 적어 메일 내용과 함께 "생성한 정보.sendMail()"로 보내는 것이다.
nodemailer 공식 메인 홈페이지의 방법대로 생성자의 정보를 만들게 된다면 위에 언급한 유튜브를 참고하는 것을 추천한다.
보내는 메일 내용에 대해서 조금 더 자세히 설명하자면 다음과 같다.
🔥from: 보내는 사람의 이메일, 보내는 사람의 정보에 넣은 이메일과 동일한 이메일을 넣어주면 된다.
🔥to: 받는 사람의 이메일
🔥subject: 보내는 이메일의 제목
🔥text: 이메일의 본문에 들어가는 내용
🔥html: 이메일의 본문에 들어가는 html형태의 내용
이 때, text와 html 둘 중 하나만 써도 되는데 일정한 크기의 텍스트들로 메일의 내용을 넣을 것이라면 text를 선택해서 내용을 적으면 되고, 글씨의 크기나 모양등을 바꾸고 싶다면 html형태로 만들면 된다.
NestJS, typeORM을 적용해 google 인증메일 보내기
// 멤버 초대
async inviteMember(invitationDto: InvitationDto) {
const {memberEmail} = invitationDto
const verificationCode = await this.createVerificationCode(memberEmail)
const email = {
service: 'gmail',
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
};
const content = {
from: process.env.EMAIL_USER,
to: `${memberEmail}`,
subject: '보드 초대 확인 인증 번호',
text: `${verificationCode}`,
};
await this.sendEmail(email, content);
return memberEmail
}
// 이메일 전송
async sendEmail(email: object, data: object) {
nodemailer.createTransport(email).sendMail(data, function (error, info) {
if (error) {
console.log(error);
} else {
console.log(info);
return info.response;
}
});
}
// 인증 코드 생성 및 DB 저장
async createVerificationCode(memberEmail:string) {
const verificationCode = (await randomBytesAsync(6)).toString('hex');
const expiry = new Date();
expiry.setTime(expiry.getTime() + this.expiry_duration)
await this.emailVerificationRepository.save({
email: memberEmail,
code: verificationCode,
expiry
})
return verificationCode
}
프로젝트를 진행하며 직접 만든 코드이고, board.service.ts 파일에서 일부를 발췌한 것이다. (이메일 인증 로직 같은 경우는 적혀있지 않다. 인증 코드같은 경우는 직접 만들어주었다)
공식홈페이지의 nodemailer와 다른 점을 설명하자면 공식홈페이지에서는 메일 보내는 사람의 정보에 host, port, secure을 적어주어야 했는데 google 메일로 보내는 것은 service: "gmail"만 적어주면 된다.
추가적으로 auth부분의 user에는 보내는 사람의 이메일을, pass에는 앱 비밀번호를 넣어주어야 한다.
❗앱 비밀번호는 계정관리 - 보안 에서 만들면 되는데 앱 비밀번호 만들기가 안보인다면 계정관리 - 보안 - 2단계 인증을 사용하는 로그인이 사용 설정됨 - 설정관리 를 누르게 되면 앱 비밀번호를 만드는 페이지로 갈 수 있다.
이외에 .env파일로 관리하거나 넣을 이메일을 파라미터로 받아오는 듯한 것만 조금 수정했다.
이렇게 만들게 되면 정상적으로 google 메일이 보내지게 된다.
'Node.js' 카테고리의 다른 글
[Node.js] nodemon (0) | 2023.11.28 |
---|---|
Backend -> Frontend로 쿠키 보내기(with Token) (0) | 2023.11.28 |
[Node.js] Access Token & Refresh Token 을 이용한 로그인 / 로그아웃 (0) | 2023.11.24 |
Express를 이용해 서버 만들기 (2) | 2023.11.14 |
모듈 (0) | 2023.11.11 |