티스토리 뷰
services 폴더에는 controller에서 필요한 기능(함수)들을 보관했다.
starbucks_controller.js
import { Starbucks } from "../models/starbucks.model.js";
export class StarbucksController {
getStarbucks = async (req, res) => {
const result = await Starbucks.find();
res.send(result);
return;
};
}
스타벅스컨트롤러다. 겟 함수가 있는데, 모델을 통해서 디비에 있는 데이터를 모두 가져오란 뜻이다.
getStarbucks가 어디서 쓰이는지 알아보자.
index.js는 MVC 패턴에 영향을 받지 않는다.
index.js
import express from "express";
import swaggerUi from "swagger-ui-express";
import swaggerJsdoc from "swagger-jsdoc";
import dotenv from "dotenv";
import mongoose from "mongoose";
import cors from "cors";
import { options } from "./swagger/config.js";
import { TokenController } from "./controllers/token_controller.js";
import { UsersController } from "./controllers/users_controller.js";
import { StarbucksController } from "./controllers/starbucks_controller.js";
const app = express();
app.use(express.json());
app.use(cors());
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerJsdoc(options)));
dotenv.config();
const tokenController = new TokenController();
app.get("/tokens/phone", tokenController.getToken);
app.post("/tokens/phone", tokenController.postToken);
app.patch("/tokens/phone", tokenController.patchToken);
const usersController = new UsersController();
app.get("/users", usersController.getUsers);
app.post("/users", usersController.postUsers);
const starbucksController = new StarbucksController();
app.get("/starbucks", starbucksController.getStarbucks); // 여기에서 쓰인다
mongoose.connect("mongodb://my_database:27017/codecamp");
app.listen(3000);
StarbucksController 객체를 만들어서 getStarbucks함수를 쓴다. 하지만 (), 소괄호는 쓰지 않는다. 함수를 바로 실행하고 싶지 않기 때문이다. 여담으로 js에선 함수또한 한 객체이다. 따라서 이렇게 쓰기가 가능하다.
TokenController 마찬가지로 자신의 함수를 썼다. TokenController를 써보자.
token_controller.js
import { Token } from "../models/token.model.js";
import {
checkValidationPhone,
getToken,
sendToken2SMS,
} from "./sevices/token_services/phone.js";
export class TokenController {
getToken = async (req, res) => {
console.log(res);
const result = await Token.find();
res.send(result);
return;
};
postToken = async (req, res) => {
console.log(req.body);
const phone = req.body.phone;
// 1. 휴대폰 번호 자리수 확인
if (!checkValidationPhone(phone)) {
res.send(false);
return;
}
const myToken = getToken(6);
// 3. 휴대폰 번호에 토큰 전송, 위치 다시 생각해보자
// sendToken2SMS(phone, myToken); // 정말로 보내지니 쓸 때만 주석 해제
// 입력받은 폰번호랑 같은 객체 찾는다.
const prevTokenPhone = await Token.findOne({ phone: phone });
// 이미 있다면 최신 토큰으로 덮어씌우기
if (prevTokenPhone) {
prevTokenPhone.token = myToken;
await Token.updateOne({ phone: phone }, { token: myToken });
res.send(true);
return;
}
const token = new Token({
token: myToken,
phone: phone,
isAuth: false, // 자동으로 주자.
});
await token.save(); // 몽고디비로 저장된다. 좀 기다려줘
res.send(true);
return;
};
patchToken = async (req, res) => {
const phone = req.body.phone;
const token = req.body.token;
//! 핸드폰 번호 이미 저장됐는지 확인
const tokenPhone = await Token.findOne({ phone: phone });
// 토큰자체가 디비에 없다면
if (!tokenPhone) {
res.status(422).send("휴대폰 인증하세요.");
return;
}
//! 발급한 토큰과 일치하는지 확인
if (tokenPhone.token !== token) {
console.log(tokenPhone);
res.status(422).send("토큰 인증이 올바르지 않습니다.");
return;
} else {
console.log(tokenPhone);
await Token.updateOne({ phone: phone }, { isAuth: true });
res.send(true);
return;
}
};
}
getToken, postToken, patchToken으로 나눴다. 기능은 기존과 마찬가지다. 하지만 이렇게 나눠놓으면 보기도 편하며 나중에 관리할 때 수월해진다.
service폴더에서 controller에 쓰이는 기능들을 담아놨다. 알아보자
token_services에는 phone.js를 담고 있다.
phone.js
import axios from "axios";
export const checkValidationPhone = (myphone) => {
if (myphone.length !== 10 && myphone.length !== 11) {
console.log("에러 발생! 핸드폰 번호를 제대로 입력해 주세요!!!");
return false;
} else {
return true;
}
}
export const getToken = (num) => {
// const num = 6;
if (num === undefined) {
console.log("error occured num === undefined, type the right number");
return;
} else if (num <= 0) {
console.log("error occured num <= 0 , type the right number");
return;
} else if (num > 10) {
console.log("error occured num > 10, type the right number");
return;
}
const result = String(Math.floor(Math.random() * Math.pow(10, num))).padStart(
num,
"0"
);
return result;
}
export const sendToken2SMS = async (phoneNumber, tokenNumber) => { // phoneNumber 받는 번호, tokenNumber 인증번호
const appKey = process.env.SMS_APP_KEY;
const senderPhoneNum = process.env.SMS_SENDER;
const XSecretKey = process.env.SMS_X_SECRET_KEY;
await axios.post(
// ------------ app key, secret key 같은 중요한 건 환경변수로 깃에 올리지 않는다 .env에 간다
`https://api-sms.cloud.toast.com/sms/v3.0/appKeys/${appKey}/sender/sms`, // <-------- 내걸로 바꿀 부분 appkey
//data, 필수요소 3인방!
{
body: "인증번호 : [ " + tokenNumber + " ]",
sendNo: senderPhoneNum, // 보내는 휴대폰번호
recipientList: [
// 받을 사람
{
internationalRecipientNo: phoneNumber, // 이 한 줄만 써도 된다
},
],
},
//header, config
{
headers: {
"X-Secret-Key": XSecretKey, // <-------- 내걸로 바꿀 부분
//-----------------------blog 쓸 것-----------------------------------------
// 키를 큰 따옴표로 한 이유: - 는 큰 따옴표로 감싸야 정상 작동되기 때문
"Content-Type": "application/json;charset=UTF-8",
//----------------------------------------------------------------
},
}
);
console.log("전송 완료");
console.log(tokenNumber + "보내는 사람, " + phoneNumber + "받는사람");
}
전에는 서술 안했지만 SMS전송은 NHN Cloud를 이용했다.
token에서 쓰인 함수들을 모아뒀다.
유저도 마찬가지로 get post로 나눴다.
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- GraphQL
- Callback
- function
- 호이스팅
- Spread
- 공부법
- 에러
- postman
- Rest
- 백틱
- Playground
- 명령어
- error
- NPM
- js
- 콜백
- 도커
- typeorm
- 독커
- yarn
- arrowfunction
- 프로그래머스
- 코드캠프
- arrow
- Console
- axios
- nodemon
- 코딩습관
- elasticsearch
- docker
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
글 보관함