실전 프로젝트 중에 이메일 인증을 넣으면 좋겠다는 의견이 있어서 담당하게되었다. 이메일 보내는 과정이 생각보다 까다롭기에 별도의 서버를 구축하는 경우가 있고 우리 서버는 대용량 데이터를 다루기에 가능하면 서버의 부하를 줄이고싶어 따로 lambda를 이용해서 인증메일을 보내고 응답으로 인증메일코드를 주고 프론트에서 인증처리를 하기로 했다.
우선 나는 sam을 이용해서 만들었으며 helloworld 템플릿을 수정해서 만들고 sam build 후 sam deploy --guide로 배포하였다.
const sesAccessKey = process.env.EMAIL;
const sesSecretKey = process.env.PASSWORD;
exports.handler = function (event, context, callback) {
const sendTarget = event.email;
const nodemailer = require("nodemailer");
const smtpTransport = require("nodemailer-smtp-transport");
console.log(sendTarget)
const generateRandom = function (min, max) {
const ranNum = Math.floor(Math.random()*(max-min+1)) + min;
return ranNum;
}
const transporter = nodemailer.createTransport(
smtpTransport({
service: "Gmail",
port: 465,
auth: {
user: sesAccessKey,
pass: sesSecretKey,
},
})
);
const number = generateRandom(111111,999999)
const mailOptions = {
from: sesAccessKey,
to: sendTarget,
subject: "[이게모약]인증 관련 이메일 입니다",
text: "오른쪽 숫자 6자리를 입력해주세요 : " + number
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error)
const response = {
statusCode: 500,
body: {
error: error.message,
},
};
callback(null, response);
}
const response = {
statusCode: 200,
body: {
message: `인증메일 전송에 성공하였습니다!`,
code: number,
},
};
callback(null, response);
});
};

코드는 이런식으로 짰고 트리거는 api gateway를 붙여 api gateway의 url로 Post 요청이 들어오면 이메일을 전송한다. 처음엔 api gateway를 http api로 짰다. 여기서 헤맸던게 조금 있었는데 자꾸 No recipients defined 에러가 떴다. 람다 테스트로 돌렸을 때는 잘 왔지만 포스트맨으로 직접 보낼 땐 에러가 떴다. No recipients defined 에러에 대해 찾아보니 발송대상 이메일이 없을 때 뜨는 에러로 나왔고 event.body와 event.body.email을 콘솔 찍어보니 event.body 는 { “email” : “example@example.com”}으로 잘 왔지만 event.body.email은 undefined로 왔다. 아마 undefined 값이 계속 왔기에 No recipients defined 에러가 뜬거 같았다. 그래서 구글링을 해보니 이벤트의 바디값이 "body": "A JSON string of the request payload." 이런 형식으로 오고 JSON으로 다시 파싱을 해주어야한다고 해서 파싱을 해줬더니 에러가 해결되고 인증메일이 잘 가는 모습을 확인했다.
https://stackoverflow.com/questions/46425573/nodejs-api-call-returning-undefined-to-lambda-function
Nodejs API call returning undefined to lambda function
This is the aws lambda function which will invoke an api: 'use strict'; var request = require("request") exports.handler = function (event, context,callback) { let url = "https://3sawt0jvzf.exe...
stackoverflow.com
하지만 누군가 악의적인 마음을 먹고 url로 무한 요청을 보내면 요금이 폭팔하기에 apikey를 붙여주고싶어 rest api로 수정하였다. rest api는 따로 파싱할 필요없이 값이 잘 오기에 파싱했던걸 지워줬다. 그 후 메소드를 post요청만 받게하고 x-api-key가 없으면 forbidden이 뜨게끔 구현했다.


이런 식으로 메소드를 any에서 POST로 바꾸고 API 키가 필요함을 true로 바꿔주고 사용량 계획을 추가해서 거기에 발급받은 apikey를 붙였다.
실전 프로젝트이지만 뭔가 프론트가 주가 되어서 걱정이었는데 다양한 인프라를 구성하고 보안을 신경쓰고하면 생각보다 좋은 포토폴리오가 나올 수 있을 것 같다.
'TIL' 카테고리의 다른 글
| Simple & Easy Notification Service + AWS lambda (0) | 2023.01.22 |
|---|---|
| PresignedURL S3 - Lambda image Resizing (0) | 2023.01.15 |
| github actions deploy to ecs (0) | 2022.12.25 |
| CORS (0) | 2022.12.18 |
| Decoupling, Component 패턴 (0) | 2022.12.15 |