이메일 검증에 필요한 기능을 찾다가 nodemailer이라는 npm 설치 후 사용했다.
1. db에 저장을 해서 비교, 재발행 시 patch를 하거나 시간을 주고 데이터를 삭제해보자
가장 효율적인 부분이라고 생각됬다. 이메일 인증은 빠르게 지나가야하는 부분이고 요청도 어느정도 있을거라 생각했습니다.
빠르고 효율적인 검색: Redis의 인메모리 저장소와 빠른 액세스 기능을 통해 검증 번호를 빠르게 검색할 수 있습니다. 데이터베이스를 조회할 필요 없이 Redis에서 이메일 주소에 연결된 검증 번호를 쉽게 가져올 수 있으므로, 성능을 향상시키고 대기 시간을 줄일 수 있습니다.
높은 요청량 처리: Redis는 높은 읽기 및 쓰기 처리량을 처리할 수 있도록 설계되어 있어 많은 요청이 있는 상황에서 효율적으로 처리할 수 있습니다. 동시 작업을 효율적으로 처리하여 이메일 검증에 대한 여러 요청을 성능 저하 없이 처리할 수 있습니다.
const nodemailer = require("nodemailer");
const redis = require("redis");
const bcrypt = require("bcryptjs");
const { UserInfos } = require("../models");
const redisClient = redis.createClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD,
});
require("dotenv").config();
class RedisRepository {
constructor() {
this.transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL_ADDRESS,
pass: process.env.EMAIL_PASSWORD,
},
tls: {
rejectUnauthorized: false,
},
});
// Initialize the Redis client
redisClient.on("error", (error) => {
console.error("Error connecting to Redis:", error);
});
}
async generateVerificationCode() {
const plainCode = Math.floor(100 + Math.random() * 900).toString();
try {
return plainCode;
} catch (error) {
console.error("Error generating verification code:", error);
throw error;
}
}
sendEmailVerificationCode = async (email) => {
const verificationCode = await this.generateVerificationCode();
const mailOptions = {
from: process.env.EMAIL_ADDRESS,
to: email,
subject: "Email Verification",
text: `Your verification code is: ${verificationCode}`,
};
this.transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error("Error sending email:", error);
} else {
console.log("Email sent successfully:", info.response);
console.log(typeof verificationCode);
redisClient.set(email, verificationCode.toString(), "EX", 600); // Set expiration time of 10 minutes (600 seconds)
}
});
return "success";
};
receive_email = async (verified_number, email, user_id) => {
const storedCode = await new Promise((resolve, reject) => {
redisClient.get(email, (error, value) => {
if (error) {
reject(error);
return;
}
if (!value) {
resolve(false);
return;
}
console.log(verified_number, value);
if (verified_number === value) {
resolve(true);
} else {
resolve(false);
}
});
});
console.log(storedCode);
if (storedCode === true) {
await UserInfos.update({ auth: true }, { where: { user_id: user_id } });
await redisClient.del(email);
}
return storedCode;
};
}
module.exports = RedisRepository;
힘들었던 troubleShoot : 바로 promise를 적용안해줬을때였다.
const storedCode = await new Promise((resolve, reject)
여기서 왜? await 이 있는데 Promise 가 왜 또 필요할까?
이유는 간단했다. 해결 : return 값을 기다렸다 반환하는 개념이 중요한게 아니였다. 흔히 사용했던 fetch등 promise를 자체를 반환하는 것을 너무 그려러니 받아드린듯하다.
하지만! 이번에는 promise 값을 리턴하는게 아니라서! 그냥 callback 함수라서! new Promise를 사용해야하는것이다!