4주 프로젝트 개.고.수 - 3

이재익·2019년 11월 27일
0
post-thumbnail

이메일 인증 기능

서버 설정을 끝마치고 가장 먼저 구현한 기능은 이메일 인증 기능이다.
이메일 중복 확인을 하면 입력한 이메일 주소로 인증 문자를 보내서
인증 문자를 통하여 본인 확인을 할 수 있는 기능을 만들었다.

이메일 인증 기능을 구현하기 위해 사용한 모듈은 nodemailer이다.
nodemailer는 이메일을 보내주는 모듈인데 무료로 이메일을 보내기 위해서
sendgrid 서비스를 이용하였다.
이때까지만 해도 몰랐지만 g-mail을 이용해도 상관없다.

// 이메일을 보내기 위한 코드
import nodemailer from "nodemailer";
import sgTransport from "nodemailer-sendgrid-transport";
import { adjectives, nouns } from "./words";

export const generateSecret = () => {
  const randomNumber = Math.floor(Math.random() * adjectives.length);
  return `${adjectives[randomNumber]} ${nouns[randomNumber]}`;
};

const sendMail = email => {
  const options = {
    auth: {
      api_user: process.env.SENDGRID_USERNAME,
      api_key: process.env.SENDGRID_PASSWORD
    }
  };

  const client = nodemailer.createTransport(sgTransport(options));
  return client.sendMail(email);
};

export const sendSecretMail = (address, secret) => {
  const email = {
    from: "gaegosu@naver.com",
    to: address,
    subject: "SingUp Secret for Gaegosu",
    html: `Hello Your login secret it <h1>${secret}</h1>.<br/> Copy paste on the Web to Sign Up`
  };

  return sendMail(email);
};

문자 생성을 해주는 사이트를 이용하여 랜덤한 문자열 500가지를 만들어서 이용했다.
generateSecret 함수를 이용하면 그 500가지 문자열을 랜덤으로 조합하여 결과를 반환한다.

그 랜덤 문자를 입력한 이메일로 발송해주는 시스템이다.

// 스키마 파일
type Query {
  emailSend(address: String!): Boolean!
  emailAuth(address: String!, randomWord: String!): Boolean!
}
// 레졸버 파일
import { User, EmailAuth } from "../../../../../models/index";
import { generateSecret, sendSecretMail } from "../../../../utils/email";

export default {
  Query: {
    emailSend: async (_, args) => {
      const { address } = args;

      const result = await User.findOne({
        where: { email: address }
      })
        .then(data => {
          if (data) return false;

          const randomWord = generateSecret();

          return EmailAuth.create({ email: address, randomWord });
        })
        .then(emailAuth => {
          const { email, randomWord } = emailAuth;
          sendSecretMail(email, randomWord);
          return true;
        })
        .catch(err => {
          console.log("errrr");
          console.log(err);
        });

      return result;
    },

    emailAuth: async (_, args) => {
      const { address, randomWord } = args;

      const result = await EmailAuth.findOne({
        where: { email: address, randomWord },
        order: [["id", "DESC"]]
      })
        .then(data => {
          if (data) {
            return EmailAuth.destroy({ where: { email: address } })
              .then(_ => true)
              .catch(err => console.log(err));
          }

          return false;
        })
        .catch(err => console.log(err));

      return result;
    }
  }
};
profile
열정 있는 개발자

2개의 댓글

comment-user-thumbnail
2019년 11월 27일

async 를 쓰는데 then 을 이렇게 여러번 사용하시면 불편할 수 있을 것 같아요!

try {
  const user = await User.findOne({ ... });
  if (!user) return null;
  const randomWord = generateSecret();
  const emailAuth = await EmailAuth.create({ ... });
  const { email, randomWord } = emailAuth;
  ...
} catch (e) {
   ...
}

요런건 어때요?

1개의 답글