Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Contributors

AltStyle によって変換されたページ (->オリジナル) /