2차 프로젝트는 텀블벅(https://tumblbug.com/)을 모티브로 웹페이지를 모델링했습니다.
이번 프로젝트에서는 1차에서는 구현해보지 못한 기능들을 구현해서 기능이 상대적으로 적어보일 수 있지만 알짜배기로다가 구현했기 때문에 더 진화를 했다 할 수 있습니다.
프로젝트 정보
- 기간 : 2022년 11월 28일 ~ 12월 9일 (2주)
- 팀원 : Frontend 4명, Backend 2명
- 레포지토리 : https://github.com/wecode-bootcamp-korea/39-2nd-bugbug-backend
구현한 기능
1. 소셜 로그인 (카X오)
- 사용자의 편의를 위해 이미 가입되어있는 소셜 로그인 기능 구현
- 카X오 REST API를 이용하여 인가코드 받기, 토큰 받기, 사용자 로그인 처리를 진행
- 프론트엔드 서버에서 카X오 계정 로그인 및 동의 후 Redirect URI로 인가 코드 전달
→ axios 모듈 이용하여 카X오 토큰 발급
→ ID 토큰 유효성 검증 및 발급받은 토큰으로 사용자 정보 조회/ 가입 처리
카X오 토큰 발급
const getKakaoAccessToken = async (authorizationCode) => {
const response = await axios({
method: "post",
url: "https://kauth.kakao.com/oauth/token",
headers: {
"Content-type": "application/x-www-form-urlencoded;charset=utf-8",
},
data: qs.stringify({
grant_type: GRANT_TYPE,
client_id: REST_API_KEY,
redirect_uri: REDIRECT_URI,
code: authorizationCode,
}),
});
return response;
};
ID 유효성 검증
const getKakaoUserInfo = async (kakaoAccessToken) => {
return await axios({
method: "get",
url: "https://kapi.kakao.com/v2/user/me",
headers: {
"Content-type": "application/x-www-form-urlencoded;charset=utf-8",
Authorization: `Bearer ${kakaoAccessToken}`,
},
});
};
2. Project 업로드
- 사용자의 편의를 위해 이미지를 AWS S3 버킷 저장 기능 구현
- 프론트엔드 서버에서 json 화된 formdata를 받아와 multer 모듈을 이용하여 file 추출
- aws-sdk 모듈을 이용하여 S3에 저장 및 삭제
require("dotenv").config();
const S3 = require("aws-sdk/clients/s3");
const fs = require("fs");
const multer = require("multer");
const util = require("util");
const bucketName = process.env.AWS_BUCKET_NAME;
const region = process.env.AWS_BUCKET_REGION;
const accessKeyId = process.env.AWS_ACCESS_KEY;
const secretAccessKey = process.env.AWS_SECRET_KEY;
const upload = multer({ dest: "uploads/" }).single("file"); //multer를 이용하여 로컬에 저장을 해야하더라고요
const unlinkFile = util.promisify(fs.unlink); // 그 다음 로컬에 저장된 파일을 삭제하는 함수
const s3 = new S3({
region,
accessKeyId,
secretAccessKey,
});
// S3에 파일 업로드
function uploadFile(file) {
const fileStream = fs.createReadStream(file.path);
const uploadParams = {
Bucket: bucketName,
Body: fileStream,
Key: file.filename,
};
return s3.upload(uploadParams).promise();
}
// S3 파일 삭제
function deleteFile(key) {
const deleteParams = {
Bucket: bucketName,
Key: key,
};
s3.deleteObject(deleteParams).promise();
}
module.exports = { upload, unlinkFile, uploadFile, deleteFile };
S3에 파일 올리는 것은... 외국인 형이 가르쳐준게 아주 컸습니다. 알려드릴게요.
https://www.youtube.com/watch?v=NZElg91l_ms&list=WL&index=2&t=783s 이 형이 잘하더라고요 ㅎㅎ
3. 후원하기
- 토X페이먼츠 이용하여 결제 기능 구현(토X는 친절하더라고요)
- 프론트엔드 서버에서 success redirect uri에서 필요한 parameter를 추출해 백엔드 서버로 보내주면 됩니다.
https://{ORIGIN}/success?paymentKey={PAYMENT_KEY}&orderId={ORDER_ID}&amount={AMOUNT}
결제를 하면 이런식으로 프론트엔드 서버로 uri가 전송되고 필요한 parameter를 request 받고
const axios = require("axios").default;
const options = {
method: 'POST',
url: 'https://api.tosspayments.com/v1/payments/confirm',
headers: {
Authorization: 'Basic dGVzdF9za196WExrS0V5cE5BcldtbzUwblgzbG1lYXhZRzVSOg==',
'Content-Type': 'application/json'
},
data: {
paymentKey: 'OQRtLKOZQnD0a4O_sFsgr',
amount: 15000,
orderId: 'QV8mB2O-R9RaCZEpLbPSM'
}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
받은 uri parameter를 axios 내부에 넣어서 보내주면 됩니다. (위에는 토X 예시 코드입니다.)
이외의 기능들은 1차 프로젝트에서 사용해 봤고, 1차 때보다 database 량이 줄어 코드가 더 간단해져서 1차 때의 카테고리 필터링이 더 고급지다고 생각합니다.
4. Test Code
이게 진짜 어려웠습니다. 처음하는 것은 언제나 어렵지만 도전은 아름답다고 생각합니다.
test code를 짜면서 왜 함수들을 다 layered 패턴에 넣는지 알게 되었습니다. test code를 짤 때 함수를 mocking 해야하는 상황이 나오는데, 함수를 다른 파일에 분리를 해놓으면 mocking 할 때 불편함이 없더라고요. (제가 아직 부족해서 그럴수도.... ㅎ)
const request = require("supertest");
const axios = require("axios");
const { createApp } = require("../app");
const { database } = require("../src/models/dataSource");
jest.mock("axios");
이런식으로 axios를 mocking 하여 test 코드 안에 넣어서
it("Success : should return project data with 200 status code when authorization code exists", async () => {
const token = {
넣고 싶은 변수값 넣으세요
};
const userInfo = {
data: {
넣고 싶은 변수값 넣으세요
};
await axios.mockResolvedValue(token);
await axios.mockResolvedValue(userInfo);
await request(app).get("/user/signin?code=213123").expect(200);
});
axios를 2개 사용했기 때문에, 두번을 작성해 놓았습니다.
mock은 생각보다 신기한 기능이라고 생각이 됩니다. 유투브 코딩앙마님이 설명해주신 내용을 토대로 이해하니까 좋더라고요. 링크 공유할게요. (사랑해요 코딩앙마)
그리고 git 가보시면 test code 있으니까 확인해 보세요.
https://www.youtube.com/watch?v=9xBjErtlr1o&t=678s
느낀점
1차 프로젝트에 비해서 소통면이나 진행 사항 관리가 더 잘 되었다고 생각됩니다.
새로운 기능과 test code 때문에 첫 스프린트까지 많은 것을 하지 못했지만, 배운 것은 많았다고 생각합니다.
다음 프로젝트에서는 지금까지 배웠던 것을 더 사용하고 응용하여 속도를 빠르게 할 것이고, 또 새로운 기능을 구현할 때 공식문서를 잘 읽어보고 부족하다면 다른 사람들의 코드들을 확인하면서 성장하고 싶다고 생각했습니다.
구현 영상
'코딩 개발' 카테고리의 다른 글
Node.js - Crawling(크롤링) (0) | 2022.12.14 |
---|---|
Node.js - 스케줄러 (0) | 2022.12.13 |
Nginx (0) | 2022.12.08 |
Proxies & Load Balancing (0) | 2022.12.07 |
Git flow (0) | 2022.11.28 |