2019. 07. 21 수정
1. nodemailer
웹 서비스에서 메일 전송은 회원의 비밀번호 찾기, 프로모션 발송, 가입 인증 등 여러 방면에서 활용할 수 있습니다.
nodemailer는 node서버에서 메일을 보낼 수 있는 메일 전송 모듈입니다.
( nodemailer의 공식 문서는 여기를 참고해주세요 ! )
메일 전송 서비스는 mailgun, AWS SES 등 많이 있습니다.
저는 주로 AWS SES를 사용했었는데, nodemailer의 사용법이 매우 심플하여 소개하고자 합니다.
위의 사진은 nodemailer의 특징을 공식문서에서 캡쳐한 것입니다.
nodemailer 모듈은 메일을 전송할 수 있고, 보안성이 좋으며, 유니코드 지원, HTML 문서를 메일 내용으로 사용, 파일 첨부 가능 등의 특징이 있습니다.
또한 Gmail을 사용하면 하루에 최대 500통의 메일을 보낼 수 있습니다. ( 원문 - 링크 )
따라서 소규모의 사이트에서 사용하기에 좋으며, 많은 메일을 발송해야 한다면 위에서 언급한 SES, Mailgun 같은 메일 서비스를 이용하시면 될 것 같습니다.
이 글에서는 nodemailer로 메일을 전송하는 방법과 메일 인증을 통한 회원가입을 구현하는 조금 더 응용된 예제를 살펴보도록 하겠습니다.
발송 메일은 Gmail을 사용할 것이며, 수신 메일의 주소는 어떠한 것이든 상관이 없습니다.
( 네이버로도 메일을 발송할 수도 있으며 이에 대한 블로그는 여기를 참고해주세요 ! )
2. 예제
먼저 nodemailer 모듈을 설치합니다.
# npm install nodemailer
이어서 클라이언트로부터 메일을 보낼 이메일 주소를 받기 위해, 뷰 페이지를 생성합니다.
views/index.ejs
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<form action="/nodemailerTest" method="post">
<input type="text" name="email">
<input type="password" name="pwd">
<input type="submit" value="회원가입">
</form>
</body>
</html>
다음은 메일을 전송하는 라우터 함수를 작성할 것인데, 예제 코드를 w3schools에서도 소개하고 있습니다.
w3chools의 예제 코드를 기반으로 라우터 함수를 작성해보겠습니다. ( 참고 )
routes/index.js
const express = require('express');
const nodemailer = require('nodemailer');
const router = express.Router();
router.post("/nodemailerTest", function(req, res, next){
let email = req.body.email;
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'youremail@gmail.com', // gmail 계정 아이디를 입력
pass: 'yourpassword' // gmail 계정의 비밀번호를 입력
}
});
let mailOptions = {
from: 'youremail@gmail.com', // 발송 메일 주소 (위에서 작성한 gmail 계정 아이디)
to: email , // 수신 메일 주소
subject: 'Sending Email using Node.js', // 제목
text: 'That was easy!' // 내용
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
}
else {
console.log('Email sent: ' + info.response);
}
});
res.redirect("/");
})
module.exports = router;
1)
nodemailer로 메일을 발송하기 위해, createTransport( transport [, defaults] ) 메서드를 호출하여 메일 발송 객체를 생성합니다.
createTransport() 메서드의 첫 번째 매개변수인 transport는 transporter 객체에 대한 환경설정 내용을 객체로 받습니다.
위 예제에서는 기본 설정인 SMTP transport를 사용 했지만, 그 밖에 다른 transport를 사용할 수도 있습니다.
예를 들면, AWS SES, JSON, stream 등이 있습니다. ( 참고 )
어쨋든 createTransport() 메서드를 호출하여 메일을 전송할 수 있는 객체를 생성합니다.
2)
다음으로 transporter 객체의 sendMail( data [, callback] ) 메서드를 호출하면 메일을 발송할 수 있습니다.
- 첫 번째 인자는 data는 메일의 내용물에 대한 정의를 작성한 객체( mailOptions )를 전달하고,
- 두 번째 인자는 콜백 함수를 정의하여, 에러( error )와 결과에 대한 정보( info )를 받을 수 있습니다.
3)
sendMail() 메서드의 첫 번째 매개변수( 메일 내용물에 대한 정의 )는 객체로 만들어 전달하는 것이 좋습니다.
그래서 mailOptions 객체를 만들었고, 이 객체는 from, to, subject, text 프로퍼티를 갖고 있습니다.
이들은 메일을 전송할 때 필요한 기본적인 프로퍼티들이고, 그 밖에 옵션들은 다음과 같습니다.
더 많은 옵션의 설명과 사용법은 여기를 참고해주세요
이 예제는 메일을 전송하는 것이 목적이므로, 추가적인 기능이 더 필요하다면 문서를 참고해주세요.
이제 회원가입 폼과, 메일을 발송하는 라우터 함수를 작성했으니 서버를 실행하고 회원가입을 진행해보겠습니다.
그러면 아마 대부분은 아래의 사진과 같은 에러가 발생할 것입니다.
구글 계정에 대한 로그인이 되지 않았다는 오류인데, 이 오류의 해결은 링크를 클릭해서 "사용함"으로 바꾸면 됩니다.
사용함으로 바꾸셨으면 다시 회원가입을 요청해서 정말로 메일이 왔나 확인해보세요.
( 테스트가 끝나면 다시 사용 안함으로 바꾸시길 바랍니다. )
3. 메일 인증을 통해 회원가입 승인하기
지금까지 nodemailer로 메일을 보내는 방법에 대해 알아보았습니다.
이번에는 회원가입 버튼을 눌렀을 때 바로 회원가입을 승인하지 않고,
메일 내용에 링크를 걸어 링크를 클릭했을 때만 회원가입이 승인되는 실용적인 예제를 작성해보도록 하겠습니다.
회원가입 입력 폼은 그대로 두고, /routes/nodemailerTest 라우터에서 mailOptions 객체만 수정하도록 하겠습니다.
let mailOptions = {
from: 'youremail@gmail.com',
to: email,
subject: '안녕하세요, OOOO입니다. 이메일 인증을 해주세요.',
html: '<p>아래의 링크를 클릭해주세요 !</p>' +
"<a href='http://localhost:3000/auth/?email="+ email +"&token=abcdefg'>인증하기</a>"
};
지금은 로컬에서 진행하고 있기 때문에 링크의 URL을 localhost로 했습니다.
도메인이 있다면 도메인을 입력하시면 되겠죠?
그리고 URL에 Query string으로 수신자의 메일 주소와 토큰을 전달합니다.
- 메일 주소를 추가한 이유는 DB에서 회원가입 승인 상태를 바꾸기 위해 key가 필요하기 때문입니다.
- token은 올바른 경로로 전달이 되었는지 확인하는 용도입니다.
- 따라서 token 값은 암호화를 해주는 것이 좋겠지만, 여기서는 간단하게 평문으로 "abdefg"를 넘겨줬습니다.
이제 /auth 경로에 대한 라우터 함수를 작성해보도록 하겠습니다.
/routes/auth
router.get("/auth", function(req, res, next){
let email = req.query.email;
let token = req.query.token;
// token이 일치하면 테이블에서 email을 찾아 회원가입 승인 로직 구현
})
어떻게 구현해야 할지 느낌만 아는 것이 이번 예제의 목적이였기 때문에, 구체적인 구현은 생략하도록 하겠습니다.
이상으로 nodemailer로 메일을 발송하는 방법에 대해 알아보았습니다.
AWS SES, mailgun 등 이메일 서비스를 이용하는 것보다 더 심플하기 때문에 간단한 서비스에서 활용하기 좋을 것 같습니다.