- 3-Layered Architecture, OOP, RDB(MySQL) 데이터 모델링, JWT, Express Middleware를 이용한 인증 로직 추가
먼저 app.js를 실행해주세요.
nodemon src/app.js
app.js 실행중 api-docs에 가서 다음 파일들을 실행시켜 주세요
auth.http
products.http
users.http
- 3-Layered Architecture를 적용
- Controller, Service, Repository Layer는 Class를 이용해 구현
- MySQL, Prisma를 이용해 데이터베이스를 설계하고 활용합니다.
- 데이터 모델링을 통해 ERD 작성
- Prisma를 이용한 마이그레이션 코드 및 스키마 코드 작성
- 인증 관련 기능을 구현합니다.
- JWT(AccessToken)의 이해
- 회원가입 API, 로그인 API, 내 정보 조회 API, 인증 Middleware 구현
- 상품 관련 기능에 인증 로직 추가
- AWS EC2 와 Gabia를 사용한 배포 IP 주소: http://apploadbalancer-381603911.ap-northeast-2.elb.amazonaws.com/
- Request Header의 Authorization 정보에서 JWT를 가져와서, 인증 된 사용자인지 확인하는 Middleware를 구현합니다.
- 인증에 실패하는 경우에는 알맞은 Http Status Code와 에러 메세지를 반환 해야 합니다.
- Authorization에 담겨 있는 값의 형태가 표준(Authorization: Bearer )과 일치하지 않는 경우
- JWT의 유효기한이 지난 경우
- JWT 검증(JWT Secret 불일치, 데이터 조작으로 인한 Signature 불일치 등)에 실패한 경우
- 인증에 성공하는 경우에는 req.locals.user에 인증 된 사용자 정보를 담고, 다음 동작을 진행합니다.
- 내 정보 조회 API (인증 필요 - 인증 Middleware 사용)
- 인증에 성공했다면, 비밀번호를 제외한 내 정보를 반환합니다.
- 이메일, 비밀번호, 비밀번호 확인, 이름을 데이터로 넘겨서 회원가입을 요청합니다.
- 보안을 위해 비밀번호는 평문(Plain Text)으로 저장하지 않고 Hash 된 값을 저장합니다.
- 아래 사항에 대한 유효성 체크를 해야 되며, 유효하지 않은 경우 알맞은 Http Status Code와 에러 메세지를 반환해야 합니다.
- 이메일: 중복될 수 없으며, 이메일 형식에 맞아야 합니다.
- 비밀번호: 최소 6자 이상이며, 비밀번호 확인과 일치해야 합니다.
- 회원가입 성공 시, 비밀번호를 제외 한 사용자의 정보를 반환합니다.
- 이메일, 비밀번호로 로그인을 요청합니다.
- 이메일 또는 비밀번호 중 하나라도 일치하지 않는다면, 알맞은 Http Status Code와 에러 메세지를 반환해야 합니다.
- 로그인 성공 시, JWT AccessToken과 RefreshToken을 생성하여 반환합니다.
- Access Token
- Payload: userId를 담고 있습니다.
- 유효기한: 1시간
- Refresh Token
- Payload: userId를 담고 있습니다.
- 유효기한: 24시간
- Access Token
- 유효한 Access Token을 통한 요청이어야 합니다.
- Access Token이 유효하지 않거나 존재하지 않는다면, 알맞은 Http Status Code와 에러 메세지를 반환해야 합니다.
- 인증 성공 시, 쿠키와 만료된 토큰을 삭제합니다.
- 인증 필요 API 호출 시 Request Header의 Authorization 값으로 JWT를 함께 넘겨줘야 합니다.
- 인증에 실패한 경우, 알맞은 Http Status Code와 로그인이 필요합니다 라는 에러 메세지를 반환합니다.
- 인증 필요 API 호출 시 Request Header의 Authorization 값으로 JWT를 함께 넘겨줘야 합니다.
- 인증에 실패한 경우, 알맞은 Http Status Code와 로그인이 필요합니다 라는 에러 메세지를 반환합니다.
- API 호출 시 상품명, 작성 내용,
작성자명, 비밀번호를 전달 받습니다. → 작성자명, 비밀번호 대신 인증에 성공한 사용자의 userId를 저장합니다. - 상품은 두 가지 상태, 판매 중(
FOR_SALE
)및 판매 완료(SOLD_OUT
) 를 가질 수 있습니다. - 상품 등록 시 기본 상태는 판매 중(
FOR_SALE
) 입니다.
- 상품명, 작성 내용, 상품 상태,
비밀번호를 데이터로 넘겨 상품 수정을 요청합니다. → 인증 기능으로 인해 비밀번호는 필요가 없습니다. - 수정할 상품과
비밀번호 일치 여부를 확인한 후, 동일할 때에만 글이 수정되어야 합니다. → 인증에 성공한 사용자의 userId와 상품을 등록한 사용자의 userId가 일치할 때에만 수정되어야 합니다. - 선택한 상품이 존재하지 않을 경우, “상품 조회에 실패하였습니다." 메시지를 반환합니다.
비밀번호를 데이터로 넘겨 상품 삭제를 요청합니다. → 인증 기능으로 인해 비밀번호는 필요가 없습니다.- 수정할 상품과
비밀번호 일치 여부를 확인한 후, 동일할 때만 글이 삭제되어야 합니다. → 인증에 성공한 사용자의 userId와 상품을 등록한 사용자의 userId가 일치할 때에만 삭제되어야 합니다. - 선택한 상품이 존재하지 않을 경우, “상품 조회에 실패하였습니다." 메시지를 반환합니다.
- 상품 ID, 상품명, 작성 내용, 작성자명, 상품 상태, 작성 날짜 조회하기
- 상품 ID, 작성 내용 항목이 지난 과제에 실수로 빠져있었습니다.
- 작성자명을 표시하기 위해서는 상품, 사용자 Table의 JOIN이 필요합니다.
- 상품 목록은 작성 날짜를 기준으로
내림차순(최신순) 정렬하기- QueryString으로 sort 항목을 받아서 정렬 방식을 결정합니다.
- 들어올 수 있는 값은 ASC, DESC 두가지 값으로 대소문자 구분을 하지 않습니다.
- ASC는 과거순, DESC는 최신순 그리고 둘 다 해당하지 않거나 값이 없는 경우에는 최신순 정렬을 합니다.
- 상품 ID, 상품명, 작성 내용, 작성자명, 상품 상태, 작성 날짜 조회하기
- DB_HOST=
- DB_USER=
- DB_PASSWORD=
- DB_DATABASE=
- DB_DIALECT=
- JWT_SECRET=
-
Class와 Instance가 각각 무엇인지 설명해 주세요.
Class(클래스): 클래스는 객체(인스턴스)를 생성하기 위한 일종의 설계도 또는 템플릿입니다. 클래스는 객체의 속성(멤버 변수)와 동작(메서드)을 정의하며, 객체를 생성하기 위한 틀 역할을 합니다. Instance(인스턴스): 인스턴스는 클래스를 기반으로 실제로 생성된 객체를 말합니다. 클래스로부터 만들어진 개별적인 객체는 각자의 고유한 속성을 가지며, 클래스에서 정의한 메서드를 호출할 수 있습니다.
-
Class의 Method는 화살표 함수(Arrow Function) 형태로 구현하지 않았을 때 발생할 수 있는 문제와 해당 문제를 해결할 수 있는 다른 방법을 적어주세요. (Hint:
this bind
)문제: 화살표 함수를 사용하면 함수 내부에서의 this는 해당 함수가 선언된 context를 가리킵니다. 따라서 클래스 메서드 내에서 화살표 함수를 사용하면 클래스 인스턴스를 가리키는 this가 정상적으로 동작하지 않을 수 있습니다. 해결 방법: 일반적인 함수 선언으로 메서드를 구현하거나, 메서드 내에서 this가 현재 인스턴스를 가리키도록 this를 명시적으로 바인딩해야 합니다. 예를 들어, 생성자에서 bind를 사용하거나 화살표 함수를 인스턴스 메서드로 정의할 때에는 클래스 프로토타입에 메서드를 추가할 수 있습니다.
-
3-Layered Architecture의 장점과 단점을 아는대로 적어주세요.
장점: 모듈화와 유지보수: 각 레이어는 특정 역할을 수행하므로 모듈화가 용이하고 유지보수가 편리합니다. 유연성과 재사용성: 레이어 간의 분리는 시스템을 유연하게 만들어주며, 각 레이어는 독립적으로 재사용될 수 있습니다. 테스트 용이성: 각 레이어는 독립적으로 테스트할 수 있어 테스트 용이성이 향상됩니다. 단점: 추가적인 복잡성: 레이어가 많아질수록 시스템의 복잡성이 증가할 수 있습니다. 성능 영향: 레이어 간의 통신이 빈번하게 일어날 경우 성능에 영향을 미칠 수 있습니다.
-
숙련주차 과제에서 Mongoose를 Sequelize로 교체 했을 때와 비교하여 이번 과제에서 Sequelize를 Prisma로 교체하는 작업은 더 쉬웠나요? 더 어려웠나요? 왜 그런지 3-Layered Architecture를 기반으로 설명해 주세요.
Sequelize to Prisma: 더 쉬웠던 이유: Prisma를 사용하니까 모델 파일을 안적어도 되고, 시간을 아낄수있었습니다. 더 어려웠던 이유: 이번 프로젝트는 쿠키를 사용해서 만들었고, 추가 구현이 있어서 조금 더 어려웠습니다. 3-Layered Architecture와 관련하여: Prisma는 코드 생성을 통해 데이터 레이어를 간소화하고, 코드의 일관성과 가독성을 향상시킬 수 있으며, 레이어 간의 통신이 간소화되어 3-Layered Architecture를 더 쉽게 구현할 수 있었습니다.
-
테스트코드 작성의 장점과 단점을 아는대로 적어주세요.
장점: 신뢰성 확보: 테스트코드는 시스템의 각 부분이 기대한 대로 동작하는지 확인하여 신뢰성을 확보합니다. 리팩토링 용이성: 코드를 변경하거나 개선할 때, 테스트코드가 있다면 기존 기능이 여전히 정상적으로 작동하는지 확인할 수 있어 리팩토링이 용이해집니다. 문서화 역할: 테스트코드는 코드의 사용법 및 기대 동작을 문서화하는 역할을 합니다. 단점: 개발 시간 증가: 테스트코드 작성은 시간이 소요되며, 초기에는 개발에 대한 지연이 발생할 수 있습니다. 모든 상황 커버 어려움: 모든 시나리오를 테스트코드로 커버하기 어려울 수 있습니다.
-
테스트의 종류 3가지와 각각이 무엇인지 간단히 설명해 주세요.
단위 테스트(Unit Test): 코드의 최소 단위인 함수 또는 메서드를 개별적으로 테스트하는 것으로, 코드의 각 부분이 제대로 동작하는지 확인합니다. 통합 테스트(Integration Test): 여러 컴포넌트 또는 시스템 간의 상호 작용을 테스트하여 컴포넌트 간의 통합이 올바로 이루어지는지 확인합니다. 인수 테스트(Acceptance Test 또는 End-to-End Test): 시스템의 전체적인 기능을 테스트하며, 사용자의 관점에서 시스템이 기대한 대로 동작하는지 확인합니다.