Skip to content

moodCatcherProject/Back-End

Repository files navigation

6551879df85a26b0


✨무드캐처 (mood catcher)

  • 무드 캐처를 꿈꾸는 모든 일반인들을 위한 커뮤니티 사이트.
  • 패션 커뮤니티, 옷의 후기 및 리뷰 취합.

📆 프로젝트 기간

  • 2022/08/26 ~ 2022/10/07

👒 팀 소개

come with me (5)

역할 이름 git
Back-end 조권영 https://github.com/kwanyung
Back-end 황수민 https://github.com/sumin-dev
Back-end 이수범 https://github.com/subeom-lee
Front-end 박준수 https://github.com/junsu1220
Front-end 신수정 https://github.com/crystal025
UI & UX 김유나 무드캐처 FIGMA 디자인
PM 김승빈 무드캐처 FIGMA 기획

👔 Project Architecture

아키텍처

🩳 API 명세서

▶ 무드캐처 REST API 바로가기

🧦 DB 설계도(ERD)

erd최최치최최최최최최최치ㅗ치ㅚ최최최최종

👟 사용한 라이브러리(패키지)

✅ 자동 배포 git actions을 사용한 이유

  • Jenkins는 프로젝트 표준 컴파일 환경에서의 컴파일 오류 검출, 자동화 테스트 수행 등 많은 장점들이 있지만, 서버 설치도 필요하고, 호스팅을 직접 해야하기 때문에 서버 운영 및 관리 비용이 발생하며 규모가 작은 프로젝트의 경우, 설정하는데 리소스 낭비가 발생할 수 있다는 단점들이 있기 때문에 프로젝트와 맞지 않다고 느껴서 사용하지 않았음
  • Git hub actions는 기본적으로 무료이며 다른 툴을 설치하지 않아도 Github Repo에서 바로 사용 할 수 있고, 비동기 CI/CD가 가능하고, 많은 언어와 프레임워크를 지원하고 있고, YAML로 작성 할 수 있어서 일반적인 코드를 작성하듯 편집, 재사용, 공유, 포킹을 할 수 있다는 장점이 있음

⇒ 현재 프로젝트에 적용하기에 가장 적합하다고 판단하여 Git actions 선택

✅ 백엔드에서 이미지 처리를 한 이유

  • 이미지 용량 제한을 할 수 있고, DB와 S3를 연동하여 확실한 데이터 처리가 가능함. 예를 들어, 유저가 게시물을 삭제하거나 회원 탈퇴할 경우, 어떤 유저의 파일인지 추적, 처리하여 메모리 낭비를 줄이고, 데이터의 무결성을 증대할 수 있음.

✅ 관계형 데이터베이스(RDBMS)를 사용한 이유

  • 프로젝트 구조 상 유저를 중심으로 관계를 맺는 데이터가 많기 때문에 DB indexing으로 데이터 관리를 용이하게 함.

✅ 왜 session이 아닌 jwt방식을 선택했을까?

  • 세션 방식은 서버의 메모리 내부에 유저의 정보를 저장함. 유저의 수가 증가할수록 세션의 양이 많아지는 만큼 메모리에 부하가 걸릴 수 있음. 실제 서비스 배포를 위한 프로젝트에서는 유저의 수가 적지 않을 거라 예상하여 JWT 토큰 인증방식 선택. JWT는 서버의 메모리에 저장 공간을 확보하지 않고 토큰 발급 및 확인 절차만 거치므로 서버 자원과 비용을 절감할 수 있음.
  • 하지만 현재 무드캐처의 jwt 방식은 토큰의 유효기간이 만료되지 않으면 소멸하지 않기 때문에 토큰 탈취, 해킹 등 보안에 취약점을 가지고 있음. access token/refresh token으로 변경하여 보안 강화 필요.

💍 기술 소개

"dependencies"
	
    "aws-sdk": "^2.1206.0",     //aws 서비스를 사용하기 위한 라이브러리
    "bcrypt": "^5.0.1",         // 비밀번호 해쉬화를 위한 라이브러리
    "cheerio": "^1.0.0-rc.12",  //html 스크래핑을 위한 라이브러리(크롤링)
    "cookie-parser": "^1.4.6",  // 요청 된 쿠키를 추출 할 수있게 해주는 미들웨어
    "cors": "^2.8.5",           // CORS 이슈 해결을 위한 라이브러리
    "crypto-js": "^4.1.1",      // 인증번호 해쉬화를 위한 라이브러리
    "dotenv": "^16.0.1",        //.env의 정보를 환경변수로 등록해주는 라이브러리
    "express": "^4.18.1",       // 웹 서버를 구현하기 위한 라이브러리
    "helmet": "^6.0.0",         //header에 설정을 통해 웹 취약점으로부터 서버 보호
    "jsonwebtoken": "^8.5.1",   // jwt로그인 방식을 위한 라이브러리
    "morgan": "^1.10.0",        // 통신 로그를 남기기 위한 라이브러리
    "multer": "^1.4.5-lts.1",   //image를 form데이터로 받기 위한 라이브러리
    "multer-s3": "^2.10.0",     // aws s3를 multer와 연결해주는 라이브러리
    "mysql2": "^2.3.3",         // mysql을 사용할 수 있게 해주는 라이브러리
    "node-schedule": "^2.1.0",  // 시간을 설정하며 특정 함수를 자동으로 작동하게 만드는 라이브러리
    "nodemailer": "^6.7.8",     //메일 전송을 위한 라이브러리
    "nodemon": "^2.0.19",       // 서버 재 가동을 쉽게 해주는 라이브러리
    "passport": "^0.5.3",       // 인증 절차에 대한 로직을 편리하게 구성할 수 있는 모듈
    "passport-kakao": "^1.0.1", // 카카오 인증절차의 편리성 증대
    "passport-local": "^1.0.0", // 로컬 인증절차의 편리성 증대
    "sequelize": "^6.21.4",     // ORM 라이브러리
    

"devDependencies": {
    "jest": "^29.0.1",           // 테스트 코드 라이브러리
    "lint-staged": "^13.0.3",    // 코드 컨벤션을 위한 라이브러리
    "prettier": "^2.7.1",        // 코드 컨벤션을 위한 라이브러리
    "sequelize-cli": "^6.4.1",   // Sequelize 지원 라이브러리
    "supertest": "^6.2.4"        // 테스트 코드 라이브러리
  }
  

💎트러블 슈팅

이미지 리사이징
❓ 주어진 문제와 요구 사항
  • 기존
    • 사용자 경험에 치명적일 정도로 이미지 렌더링이 지연 됨.
  • 고민
    • 이미지를 불러오는 시간을 줄일 방법이 필요함.
    • 이미지의 박스 크기는 140px 185px의 크기인데 이미지의 원본의 크기는 과하게 크다는 결론.
  • 결정
    • 사용자 경험에 치명적이지 않은 선에서 이미지 리사이징을 결정.

💡 가설과 선택지
  • 백엔드 서버에서 리사이징, aws lambda를 활용한 리사이징
    • 백엔드 서버에서 리사이징을 진행하게 되면 서버의 자원을 소모하게 되고 시간도 오래걸려 서버에 무리가 가게 됨.
    • aws lambda는 달에 100만 건 까지 무료이고 serverless의 특성을 이용할 수 있어 효율적.
      • serverless : 서버에서 일을 직접 처리하지 않고 클라우드 환경에서 대신 일을 처리하는 아키텍처

🧑‍⚖️ 의사 결정과 근거, 구현
  • aws lambda를 이용해 s3에 이미지가 업로드 되면 이미지 리사이징 함수를 실행.

💡 ✅결과

모든 결과는 이미지 캐시를 삭제 한 후 테스트한 결과입니다.

💡 원본 이미지를 출력

이미지 원본GIF 원본사진 불러오는 데 걸리는 시간

💡 리사이징 된 이미지 출력

이미지 리사이징 걸리는 시간 이미지 리사이징GIF

전체 게시물 출력
❓ 주어진 문제와 요구 사항
  • 기존
    • 기능 별이 아닌 페이지를 기준으로 api를 나누었음.
      • 메인 페이지의 전체 게시물 출력, 마이 페이지 게시물 출력 등등
  • 고민
    • 페이지 별이 아닌 기능 별로 api를 구성하는 것이 좋다는 피드백
    • 형식이 아닌 데이터의 내용만 바뀌는데 굳이 이렇게 많은 api가 필요한가 라는 의문
  • 결정
    • api 하나로 충분히 데이터 전송이 가능하다는 판단 하에 api를 하나로 축소

💡 가설과 선택지
  • 현재 서비스 중인 인프런에서 url을 관찰하며 아이디어를 얻음.

    인프런

  • 서버에서 프론트에게 전달해주는 데이터는 결국 내용만 바뀌고 형식은 변하지 않기 때문에 query를 이용하면 모든 경우의 수를 고려 할 수 있다고 판단.


🧑‍⚖️ 의사 결정과 근거, 구현
  • query 값을 이용해 경우의 수를 나누는 알고리즘 생성
✅ 결과
  • 프론트에서 ?type=like&page=1&count=8 같은 정해진 규칙으로 query 변수를 전달해주면 해당 조건에서 필터링 된 게시물을 출력하는 데 성공.
  • api를 하나로 줄이는 데 성공.

현재 api명세

현재의 api명세

회원가입 / 로그인
❓ 주어진 문제와 요구사항
  • 기존
    • 회원가입을 실제로 존재하지 않는 이메일으로 회원가입을 할 수 있음 (회원가입)
    • 비밀번호를 잊었을 때 찾을수있는 수단이 없음 (비밀번호 찾기)
    • 비밀번호를 틀렸을 때 계속 비밀번호를 시도할 수 있음 (로그인)
  • 고민
    • 한 사람이 여러 계정을 가지고 좋아요를 누를수 있다 (회원가입)
    • 이메일정보가 실존하지 않기때문에 그 사람이 누구인지 알 수 없어서 게시글에 문제되는사진을 올리거나 댓글에 욕을 할 수 있는 가능성이 있다 (회원가입)
    • 사용자가 비밀번호를 잊어버렸을 때 더이상 그 계정을 사용하지 못하는 경우가 발생한다 (비밀번호 찾기)
    • 해커가 악의적으로 해킹을 위해 무차별 대입을 통해 계정을 탈취할수 있는 경우가 발생한다 (로그인)
  • 결정
    • Nodemailer를 사용하여 인증번호 방식을 통해 실제 존재하는 이메일으로만 회원가입을 할 수 있게 구현 결정 (회원가입)
    • 비밀번호 찾기 기능을 만들어서 사용자가 비밀번호를 잊어버렸을때 비밀번호를 변경할수 있도록 구현 결정 (비밀번호 찾기)
    • 비밀번호 시도에 제한을 둬서 비밀번호를 5회이상 틀렸을 때 로그인을 10분간 할 수 없도록 구현 결정 (로그인)

💡 가설
  • 구현 가능한 방법 (회원가입 / 비밀번호찾기)
      1. Nodemailer를 통해 해당 이메일에 인증번호를 보내고 해당 이메일에 인증번호를 해시화하여 DB에 저장
      1. 인증번호가 DB 해당이메일에 저장된 인증번호와 일치시 회원가입 및 비밀번호찾기 성공
  • 주기적인 인증번호 청소 (회원가입 / 비밀번호찾기)
    • Node-schedule를 사용하여 10분이 지나면 인증번호 만료로 인식후 DB에서 해당 이메일의 인증번호 삭제
  • 구현 가능한 방법 (로그인)
    • 로그인시 이메일과 비밀번호가 일치하지 않는다면 해당 이메일에 실패카운트를 1개씩 늘린다
    • 실패카운트가 5회이상일 경우 10분간 로그인이 불가능하게 한다

✅ 결과
  • 무분별한 좋아요 불가 (회원가입)
  • 게시글에 문제되는사진 댓글에 욕 작성 등 불법행동시 이메일 특정 후 신고 가능 (회원가입)
  • 비밀번호를 잊었을때 찾을수 있음 (비밀번호 찾기)
  • 해커가 무차별 대입을통한 계정 탈취를 할 수 없음 (로그인)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published