node.js - async-await / axios 활용 문자&메일 발송 / 환경변수 본문
async-await
async-await를 이해하기 위해선 동기와 비동기 개념을 이해해야 한다.
동기 : 등록이 될 때까지 기다림 / 서버 컴퓨터가 작업이 끝날 때까지 기다리는 통신
비동기 : 요청들이 서로 기다릴 필요 없을 때 사용 / 동시에 여러 일을 할 때 / 서버 컴퓨터가 작업이 끝날 때까지 기다리지 않는 통신
=> axios 와 같은 API 관련 기능들은 '비동기'가 기본값
vscode 내에서 비동기
// 비동기 통신
// 비동기로 실행되기 때문에 생기는 Promise
const data = axios.get(url - / 중략 / ) // API정보를 받아오기 전에 저장
console.log(data)
// 비동기 통신 (async / await)
// async : 함수 앞 / await 동기 작동(API)을 원하는 위치
async function () {
const data = await axios.get(url - / 중략 / )
console.log(data) // 정상적인 API정보 저장 가능
}
// 함수선언식으로 사용하는 법
const fetchSync = async() => {
const result = await axios.get("https://koreanjson.com/posts/1");
console.log("비동기 방식 : ", result); // 제대로된 결과 => {title: "...."}
console.log("비동기 방식 : ", result.data.title)
}
이때 async 와 await의 위치에 집중할 필요가 있다.
() 을 기준으로, function이 존재하면 그 앞, 없다면 ()앞에 존재하면 된다.
// 함수표현식에서의 위치
'async' function () {
const data = 'await' axios.get(url - / 중략 / )
}
// 함수선언식에서의 위치
const 함수이름 = 'async'() => {
const data = 'await' axios.get(url - / 중략 /)
}
await 의 경우, '비동기' 작동을 하고자 원하는 기능 앞에 위치시켜주면 된다.
coolSMS
coolSMS 는 rest API를 활용하여 문자보내는 사이트다.
해당 기능을 통해 문자보내는 방식
// phone.js
// coolsms 양식
import coolsms from 'coolsms-node-sdk'
const mysms = coolsms.default
// 중략 //
// 휴대폰 번호 길이 검증 & 토큰 생성 함수
// 이때 SMS_KEY & SMS_SECRET & SMS_SENDER 는 환경변수 .env 에 보관
// anync & await 사용
export async function sendTokenToSMS (myphone, result) {
const SMS_KEY = process.env.SMS_KEY // SMS_KEY API키
const SMS_SECRET = process.env.SMS_SECRET // SMS_SECRET API키 비밀번호
const SMS_SENDER = process.env.SMS_SENDER // SMS_SENDER 보내는 이
const messageService = new mysms(SMS_KEY,SMS_SECRET) // 양식
const res = await messageService.sendOne({ // 양식
to: myphone, // 양식
from:SMS_SENDER,
text: `안녕하세요? 인증번호는 ${result}입니다.`
})
console.log(res)
}
// index.js
import express from "express"; // 요즘 방식 -> module 방식
import { checkPhone, getToken, sendTokenToSMS } from "./phone.js"; // export 가져오기
import "dotenv/config"
function zzz(){ // 인증하기 버튼 누를 시 실행되는 함수
const myPhone = document.getElementById('myPhone').value
axios.post("http://localhost:3000/tokens/phone", {
qqq : myPhone // qqq 에 입력한 번호 저장
}).then((res) => {
console.log(res.data)
document.getElementById('result').innerText = res.data
})
}
app.post("/tokens/phone", function (req, res) {
console.log(req);
let myPhone = req.body.qqq; // qqq = input.value
const isValid = checkPhone(myPhone);
if (isValid == false) return; // 검증 함수
const myToken = getToken();
sendTokenToSMS(myPhone, myToken);
res.send("인증 완료!");
});
app.listen(3000);
데이터 흐름을 기억하면 좋을 것 같다.
- 브라우저(번호 입력) =>
- zzz함수 실행(API, req.body.qqq 에 번호 저장) => // axios 로 전송
- express 로 받음 // app.post 실행 => 문자 전송
** 이때 API 키와 API Secret 은 따로 '.env' 환경변수에 저장해둔 뒤 따로 관리한다.
결과물
nodemailer
nodemailer 는 메일을 rest API를 활용하여 문자보내는 사이트다.
해당 기능을 통해 이메일 보내는 방식
// email.js
import { getToday } from "./utils.js" // 가입일을 알리기 위한 함수
import nodemailer from 'nodemailer' // nodemailer 설치
// 이메일 검증 함수 생략 //
// 템플릿 만드는 함수 생략 //
// 템플릿 메일로 보내는 함수
export async function sendTemplateToEmail(email, template){ // async
const EMAIL_ID = process.env.EMAIL_ID // email_id
const EMAIL_PW = process.env.EMAIL_PW // 2차 비밀번호
const transporter = nodemailer.createTransport({
service : "gmail",
auth : {
user : EMAIL_ID,
pass : EMAIL_PW
}
})
const res = await transporter.sendMail({ // nodemailer 양식
from: "// 보내고자 하는 이메일 //",
to : email, // 양식
subject : "가입을 축하합니당",
html : template
})
console.log(res)
// index.js
// 회원등록 API
// {name,age,school,email} req.body.~에서 받아옴
app.post("/users", function(req, res){
// const name = req.body.name
// const age = req.body.age
// const school = req.body.school
// const email = req.body.email
const {name, age, school, email} = req.body // 구조분해할당
const isValid = checkEmail(email) // 검증
if(isValid == false) return
let template = makeTemplate(name,age,school) // 템플릿 함수
// 3. 이메일에 가입환영 템플릿 전송하기
sendTemplateToEmail(email, template) // 전송 함수
res.send("가입완료") // 출력 메시지
console.log(`${email}로, ${template}전달하였씁니당`)
})
app.listen(3000);
결과물 (포스트맨으로 데이터 입력 & 메일)
환경변수 .env
앞서 얘기한 환경변수에 대해 얘기를 해보자.
API 키와 API 비밀번호는 중요정보기 때문에 따로 취급할 필요가 있다.
이를 위해 생성한 파일이 '.env'인데, 이는 "환경변수"의 약자로 키값을 저장할 때 사용한다.
// .env
SMS_KEY = -----
SMS_SECRET = -----------------
SMS_SENDER = -----
EMAIL_ID = ----@gmail.com
EMAIL_PW = --------
해당 데이터는 위와 같이 변수에 할당할 수 있으며,
dotenv 을 설치한 뒤 import 'dotenv/config' 를 지정하여 변수명으로 불러올 수 있다. (이때 import는 최상위 파일)
이후 .gitignore 에 .env 을 설치하면 git에 올리지 않으면서 해당 파일을 안전하게 저장할 수 있다.
6일차 과제 : 브라우저에서 데이터를 받아와 해당 데이터로 문자 & 메일을 전송하는 기능 구현
// 문자 rest API 구현
// 1. 브라우저 입력 단계 // signup.js
const getValidationNumber = async () => {
document.querySelector("#ValidationInputWrapper").style.display = "flex";
console.log("인증 번호 전송");
const phone1 = document.querySelector("#PhoneNumber01").value;
const phone2 = document.querySelector("#PhoneNumber02").value;
const phone3 = document.querySelector("#PhoneNumber03").value;
console.log(phone1 + phone2 + phone3);
let phoneNumber = phone1 + phone2 + phone3; // 휴대폰 번호
axios
.post("http://localhost:3000/tokens/phone", { phoneNumber }) // 휴대폰 번호 post
.then((res) => {
console.log(res, "휴대폰 토큰 전송됨");
});
};
// 2. 문자 메시지 API// index.js
import express from "express";
import {checkPhone,getToken,sendTokenToSMS} from "./phone.js"
const app = express();
app.use(cors())
app.use(express.json())
app.post("/tokens/phone", function (req, res) {
console.log(req);
let {phoneNumber} = req.body
const isValid = checkPhone(phoneNumber);
if (isValid == false) res.send("인증실패")
const myToken = getToken();
sendTokenToSMS(phoneNumber, myToken);
res.send("인증 완료!");
});
// 3. 함수 및 비동기 함수 실행 phone.js
import 'dotenv/config'
import coolsms from 'coolsms-node-sdk'
const mysms = coolsms.default
// 타 기능 함수 생략 //
export async function sendTokenToSMS (myphone, result) {
const SMS_KEY = process.env.SMS_KEY
const SMS_SECRET = process.env.SMS_SECRET
const SMS_SENDER = process.env.SMS_SENDER
const messageService = new mysms(SMS_KEY,SMS_SECRET)
const res = await messageService.sendOne({
to: myphone,
from:SMS_SENDER,
text: `안녕하세요? 인증번호는 ${result}입니다.`
})
console.log(res)
}
// 1. 브라우저 입력 / signup.js
// 회원 가입 API 요청
const submitSignup = async () => {
const SignupName = document.getElementById("SignupName").value
const SignupPersonal = document.querySelector("#SignupPersonal").value
const SignupPrefer = document.querySelector("#SignupPrefer").value
const SignupEmail= document.querySelector("#SignupEmail").value
const SignupPwd = document.querySelector("#SignupPwd").value
const SignupPhone =
document.querySelector("#PhoneNumber01").value -
document.querySelector("#PhoneNumber02").value -
document.querySelector("#PhoneNumber03").value
axios.post("http://localhost:3000/signup", {SignupName,SignupPersonal,SignupPrefer,SignupEmail,SignupPwd,SignupPhone}).then((res) => {
console.log(res, "회원가입 데이터 전송됨"); // 데이터 객체 전송
});
};
// 2. rest API 실행
app.post("/signup", function(req, res){
const {SignupName,SignupPersonal,SignupPrefer,SignupEmail,SignupPwd,SignupPhone} = req.body // 구조분해할당
const isValid = checkEmail(SignupEmail)
if(isValid == false) return
let template = makeTemplate(SignupName,SignupPhone,SignupPrefer)
sendTemplateToEmail(SignupEmail, template)
res.send("가입완료")
console.log(`${SignupEmail}로, ${template}전달하였씁니당`)
})
app.listen(3000);
// 3. 메일 발송
export async function sendTemplateToEmail(email, template){
const EMAIL_ID = process.env.EMAIL_ID
const EMAIL_PW = process.env.EMAIL_PW
const transporter = nodemailer.createTransport({
service : "gmail",
auth : {
user : EMAIL_ID,
pass : EMAIL_PW
}
})
const res = await transporter.sendMail({
from: "-----@gmail.com",
to : email,
subject : "가입을 축하합니당",
html : template
})
console.log(res)
'개발 > node.js' 카테고리의 다른 글
node.js - 비동기 프로그래밍 / callback / promise / async & await (0) | 2023.01.18 |
---|---|
node.js - 가상 머신 / Docker / 포트포워딩 (0) | 2023.01.17 |
node.js - axios / CORS / apollo-server / graphQL-API(&docs) 생성 (0) | 2023.01.14 |
node.js - 서버 / 포트 / nodemon / API 함수 추가 /swagger (0) | 2023.01.13 |
node.js - 데이터 통신 기초 / API방식(REST&GRAPHQL) / CRUD / (postman & swagger || playground) / express (0) | 2023.01.11 |