diff --git a/week09/keyword/keyword.md b/week09/keyword/keyword.md new file mode 100644 index 0000000..eaecf52 --- /dev/null +++ b/week09/keyword/keyword.md @@ -0,0 +1,24 @@ +- OAuth 2.0 + + 사용자가 비밀번호를 직접 넘기지 않고도, 타 사이트의 인증을 이용해 권한을 위임받는 표준 프로토콜(비밀번호 대신 토큰으로 권한을 위임하는 로그인/인증 표준) + + 특징 + + - AccessToken을 발급받아 API 접근 + - 소셜 로그인(구글 로그인, 카카오 로그인) 등 다양한 서비스와 연동 쉬움 + - 다양한 Grant Type 존재(Authorization Code, Client Credentials 등) +- JWT + + 사용자 정보를 JSON 형태로 인코딩하여 전달하는 자체 서명 토큰 + + 보통 AccessToken으로 사용됨 + + 특징 + + - Header + Payload + Signature 구조 + - 서버가 상태(Session)를 저장할 필요x +- Bearer Token + + 이 토큰을 가진 사람은 누구든 접근 가능하다는 방식의 단순한 인증 토큰 + + HTTP 헤더에 `Authorization: Bearer ` 으로 전송 \ No newline at end of file diff --git a/week09/mission/mission.md b/week09/mission/mission.md new file mode 100644 index 0000000..1879df2 --- /dev/null +++ b/week09/mission/mission.md @@ -0,0 +1,137 @@ + +## 사용자 정보 관련하여 수정 + +### 내가 작성한 리뷰 목록 조회 API, 내가 진행 중인 미션 목록 조회 API + +path parameter (:userId) 제거 + +- 로그인한 사용자의 ID는 이미 isLogin 미들웨어를 통해 req.user에 담겨 있기 때문 + +controller 수정 + +- 기존 + + ```jsx + export const handleListUserReviews = async (req, res, next) => { + const reviews = await listUserReviews( parseInt(req.params.userId), typeof req.query.cursor === "string" ? parseInt(req.query.cursor) : 0 ); + res.status(StatusCodes.OK).success(reviews); } + }; + ``` + +- 수정 + + 로그인한 사용자 id(req.user.id) 사용 + + ```jsx + export const handleListUserReviews = async (req, res, next) => { + try { + const userId = req.user.id; + const cursor = typeof req.query.cursor === "string" ? parseInt(req.query.cursor) : 0; + + const reviews = await listUserReviews(userId, cursor); + + res.status(StatusCodes.OK).success(reviews); + } catch (err) { + next(err); + } + }; + ``` + + +### 리뷰 추가 API, 가게의 미션을 도전 중인 미션에 추가 API + +controller 수정 + +- 기존 + + ```jsx + try { + const dto = createUserMissionDto(req.body); + const userMission = await addUserMission(dto); + res.status(StatusCodes.CREATED).success(userMission); + } catch (err) { + next(err); + } + ``` + +- 수정 + + 로그인한 사용자 id 사용 + + ```jsx + try { + const dto = { + ...createUserMissionDto(req.body), + userId: req.user.id, + }; + + const userMission = await addUserMission(dto); + res.status(StatusCodes.CREATED).success(userMission); + } catch (err) { + next(err); + } + ``` + + +--- + +## 내 정보 수정 API + +`PATCH /api/v1/users/my` + +![스크린샷(293).png](https://github.com/user-attachments/assets/d642ef5b-5cad-4a08-880e-6dc80a268548) + +성공 응답, 실패 응답(커스텀에러: 401로 처리) + +![스크린샷(283).png](https://github.com/user-attachments/assets/2b98af66-8e6a-44ea-9f17-609782aebea8) + +![스크린샷(284).png](https://github.com/user-attachments/assets/066b4c3d-00e1-49a7-b522-6c04cc8a5de2) + +실행 결과 + +![스크린샷(282).png](https://github.com/user-attachments/assets/09178d86-8a60-4658-9a80-2fc00c952699) + +![스크린샷(295).png](https://github.com/user-attachments/assets/9ee553ab-946d-499a-8185-09346e3e1119) + +Postman GET /mypage 실행 + +내 정보 수정 API로 수정한 값으로 바뀐 것을 확인할 수 있다. + +--- + +## 기존 API에 JWT 적용하여 로그인한 사용자만 쓸 수 있도록 보호 + +### 미들웨어를 라우터에 적용 + +```jsx +app.post("/api/v1/stores", isLogin, handleAddStore); +... +``` + +- isLogin 미들웨어를 로그인이 필요한 API 라우터에 적용 (`index.js`) + +### swagger + +![스크린샷(285).png](https://github.com/user-attachments/assets/89a4415d-92b4-436f-8f70-1d321247c37c) + +```jsx +const doc = { + info: { + title: "UMC 9th", + description: "UMC 9th Node.js 테스트 프로젝트입니다.", + }, + host: "localhost:3000", + components: { + securitySchemes: { + BearerAuth: { + type: "http", + scheme: "bearer", + bearerFormat: "JWT", + }, + }, + }, + }; +``` + +- 기존 doc 객체에 `components.securitySchemes` 추가 (`index.js`) +- 로그인이 필요한 API 주석에 `#swagger.security = [{ "BearerAuth": [] }]` 추가 (`controller.js`) \ No newline at end of file diff --git a/week10/keyword/keyword.md b/week10/keyword/keyword.md new file mode 100644 index 0000000..eb9ca8c --- /dev/null +++ b/week10/keyword/keyword.md @@ -0,0 +1,37 @@ +- CI/CD + + 개발 → 빌드 → 테스트 → 배포 과정을 자동화하는 개발 프로세스 + + CI: 지속적 통합, 코드 변경 시 자동 빌드·테스트 + + CD: 지속적 배포, 테스트를 통과하면 자동으로 운영 환경 배포 + +- GitHub Actions + + GitHub 내에서 CI/CD 파이프라인을 구성할 수 있는 워크플로우 자동화 도구 + + YAML 파일로 워크플로우 정의 (`.github/workflows/*.yml`) + + GitHub에 내장되어 별도 CI 서버 불필요 + +- Reverse Proxy + + 클라이언트 요청을 받아 내부 서버로 전달하는 서버 + + 클라이언트는 실제 서버 주소를 모름 + + 로드 밸런싱: 여러 서버에 요청 분산 + + SSL 종료: HTTPS 요청 처리 후 내부 서버로 전달 + + 캐싱: 정적 파일 캐싱 가능 + + 보안: 서버 직접 노출 방지 + +- HTTPS + + HTTP + TLS/SSL로 암호화된 통신 프로토콜 + + 클라이언트 ↔ 서버 간 데이터 보호 + + 암호화, 인증서 기반, 무결성 \ No newline at end of file diff --git a/week10/mission/mission.md b/week10/mission/mission.md new file mode 100644 index 0000000..7b362fd --- /dev/null +++ b/week10/mission/mission.md @@ -0,0 +1,9 @@ +## 미션 기록 + +### GitHub Actions 파이프라인 작성 + +![스크린샷(296).png](https://github.com/user-attachments/assets/5759a975-8de8-4ad8-b7dc-e8c30a074fed) + +액션이 동작하도록 스크립트를 적은 후 main에 merge + +원격접속 후 터미널에서 명령어로 패키지 설치 중인데 설치가 중간에 멈춘 상황.. \ No newline at end of file