Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions week09/keyword/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
- OAuth 2.0

OAuth 2.0은 사용자의 비밀번호를 직접 공유하지 않고도 다른 애플리케이션이 사용자의 정보에 접근할 수 있도록 권한을 부여하는 개방형 표준 프레임워크이다.

**OAuth의 4가지 주요개념**

1. Resoucre Owner

: 리소스 소유자를 의미하고, 여기서 리소스란 외부 소셜 서비스(API)를 의미한다. 즉, 해당 서비스에서 리소스를 소유하고 있는 사용자를 의미하고, 서비스의 유저를 의미한다.

2. Authorization Server

: Resource Owner를 인증하고, 서비스에게 Access Token을 발급해주는 서버인, 외부 플랫폼 리소스에 접근할 수 있는지 인증하는 서버를 의미한다.

3. Resouce Server

: 실제 데이터가 있는 서버를 의미한다. (ex. 구글 API 서버, 카카오 API 서버 등)

4. Client

: 권한을 얻고 싶은 서비스를 의미한다. 즉, 사용자가 만든 서비스를 의미한다.


**OAuth 2.0의 흐름**

1. 사용자가 클라이언트 앱에서 로그인 요청
2. 클라이언트는 사용자를 인증 서버로 리다이렉션
3. 사용자가 승인하면 인증 서버가 Authroization Code를 클라이언트에게 전달
4. 클라이언트는 이 코드를 사용해 Access Token을 발급받음
5. 이후 클라이언트는 이 토큰으로 Resource Server에 접근
- JWT

JWT는 당사자 간에 정보를 JSON 객체로 안전하게 전송하기 위한 개방형 표준이다. 주로 인증(Authentication)과 정보 교환에 사용되며, 자가 수용적(Self-contained)이라는 특징이 있다.

**핵심 특징**

- **Self-contained :** 토큰 자체가 필요한 모든 정보(유저 ID, 권한, 만료 시간 등)를 포함하고 있어, 서버가 별도의 세션 저장소를 조회할 필요가 없다.
- **Stateless :** 서버는 클라이언트의 상태를 저장하지 않고, 들어오는 요청의 토큰만 검증하면 된다.

**JWT의 3가지 구조**

JWT는 점(`.`)으로 구분된 세 부분으로 구성된다. (`aaaaa.bbbbb.ccccc`)

1. **Header (헤더)**
- 토큰의 타입(JWT)과 해싱 알고리즘(HMAC SHA256 or RSA) 정보가 들어간다.
2. **Payload (페이로드)**
- 실제 전달하려는 데이터(Claim)가 담긴다.
- 사용자 ID, 유효기간(exp), 발급자(iss) 등의 정보를 포함한다.
- *주의: 암호화되지 않고 Base64로 인코딩만 되므로 민감한 정보(비밀번호 등)는 담으면 안 된다.*
3. **Signature (서명)**
- 데이터 위변조를 막기 위한 서명 부분이다.
- `Header` + `Payload` + `서버만 아는 비밀키(Secret Key)`를 조합하여 생성한다.
- Bearer Token

Bearer Token은 OAuth 2.0에서 리소스에 접근하기 위해 사용하는 토큰의 유형 중 하나이다. Bearer는 소지자라는 뜻으로, 이 토큰을 가진 사람에게 권한을 부여한다는 의미를 가진다.

**핵심 개념**

- **소유 기반 인증:** 토큰을 가지고 있는 것만으로도 해당 리소스에 접근할 수 있는 권한이 인정된다.
- **현금과 유사:** 마치 현금과 같아서, 잃어버리면 그것을 주운 사람이 사용할 수 있다. (따라서 HTTPS와 같은 암호화된 통신 위에서 사용해야 안전하다.)
- **편의성:** 복잡한 암호화 증명 과정 없이 헤더에 토큰을 넣어 보내는 것만으로 인증이 처리된다.

**사용 예시 (HTTP Header)**

클라이언트가 서버로 요청을 보낼 때, `Authorization` 헤더에 다음과 같은 형식으로 전송한다.

`Authorization: Bearer <Access Token>`
128 changes: 128 additions & 0 deletions week09/mission/mission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# 1️⃣ 하드 코딩 부분 수정

해당 없음

---

# 2️⃣ 이미 존재하는 사용자도 정보 갱신 가능

```jsx
export const getUserByEmail = async (email) => {
return prisma.user.findUnique({ where: { email } });
};

export const updateUser = async (userId, data) => {
const user = await prisma.user.findUnique({ where: { id: userId } });
if (!user) {
throw new NotFoundError("사용자를 찾을 수 없습니다.");
}
await prisma.user.update({ where: { id: userId }, data });
};

export const deleteUserPreferences = async (userId) => {
await prisma.userFavorCategory.deleteMany({ where: { userId } });
};
```

user.repository.js

```jsx
export const userSignUp = async (data) => {
const existingUser = await getUserByEmail(data.email);
let userId;

if (existingUser) {
await updateUser(existingUser.id, {
name: data.name,
gender: data.gender,
birth: data.birth,
address: data.address,
detailAddress: data.detailAddress,
phoneNumber: data.phoneNumber,
});
await deleteUserPreferences(existingUser.id);
userId = existingUser.id;
} else {
userId = await addUser({
email: data.email,
name: data.name,
gender: data.gender,
birth: data.birth,
address: data.address,
detailAddress: data.detailAddress,
phoneNumber: data.phoneNumber,
});
}

for (const preference of data.preferences) {
await setPreference(userId, preference);
}

const user = await getUser(userId);
const preferences = await getUserPreferencesByUserId(userId);
const access_token = generateAccessToken(user);
const refresh_token = generateRefreshToken(user);

return responseFromUser({
user: { ...user, access_token, refresh_token },
preferences,
});
};
```

user.service.js

```jsx
export const responseFromUser = ({ user, preferences }) => {
if (!user) throw new NotFoundError("사용자 정보를 찾을 수 없습니다.");

const preferFoods = (preferences ?? [])
.map((preference) => preference.foodCategory?.name ?? preference.name)
.filter(Boolean);

return {
access_token: user.access_token,
refresh_token: user.refresh_token,
profile: {
email: user.email,
name: user.name,
preferCategory: preferFoods,
},
};
};
```

user.dto.js

---

# 3️⃣ JWT를 기존 API들에 적용 (로그인한 사용자만 쓸 수 있도록)

```jsx
import jwt from "jsonwebtoken";
import { prisma } from "../configs/db.config.js";
import { asyncHandler } from "../utils/async-handler.js";
import { UnauthorizedError } from "../utils/errors.js";

export const requireAuth = asyncHandler(async (req, res, next) => {
const raw = (req.get("Authorization") ?? "").trim();
const parts = raw.split(/\s+/).filter(Boolean);
const token = parts.length > 1 ? parts[parts.length - 1] : parts[0];
if (!token) throw new UnauthorizedError("Authorization 헤더가 필요합니다.");

const secret = process.env.JWT_SECRET;
if (!secret) throw new UnauthorizedError("서버 JWT 설정이 되어 있지 않습니다.");

let payload;
try { payload = jwt.verify(token, secret); }
catch { throw new UnauthorizedError("유효하지 않은 토큰입니다."); }

const user = await prisma.user.findUnique({ where: { id: payload.id } });
if (!user) throw new UnauthorizedError("사용자 정보를 찾을 수 없습니다.");

req.user = user;
next();
});
```

auth.middleware.js
127 changes: 127 additions & 0 deletions week10/keyword/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
- CI/CD

### 1) 정의

- **CI (Continuous Integration, 지속적 통합)**

개발자들이 코드를 자주(하루에도 여러 번) 공용 저장소에 **통합(push)** 하고,

그때마다 **자동으로 빌드 + 테스트**를 돌려서 문제를 빨리 찾는 방식.

- **CD (Continuous Delivery / Deployment, 지속적 전달/배포)**

테스트를 통과한 코드를 **자동으로 배포 가능한 상태**까지 가져가거나,

더 나아가 **실제 운영 환경까지 자동 배포**하는 프로세스


> 한 줄로: 코드 변경 → 자동 빌드/테스트 → 자동 배포까지 이어지는 파이프라인
>

### 2) 특징 / 속성

- **자동화**: 빌드, 테스트, 배포를 스크립트/파이프라인으로 자동화
- **작은 단위 배포**: 작은 변경을 자주 배포 → 롤백/문제 파악이 쉬움
- **지속적인 피드백**: 테스트 실패, 품질 이슈를 빠르게 알 수 있음
- **DevOps 문화의 핵심**: 개발+운영 협업을 전제로 함

### 3) 장점

- 버그를 **빨리 발견** → 수정 비용 감소
- 배포가 **일상 업무**가 되어서, 릴리스 공포(“배포 공포증”) 줄어듦
- 기능 출시 속도 ↑, 제품 품질 ↑

### 4) 단점 / 도입 시 고려사항

- 파이프라인 구축 초기에 **시간/노력/인프라 비용**이 듦
- 테스트/자동화가 허술하면 **문제를 더 빨리 퍼뜨리는 파이프라인**이 되어버릴 수도 있음
- 조직 문화(코드 리뷰, 브랜칭 전략 등)가 같이 정비되어야 효과가 큼
- GitHub Actions

### 1) 정의

- GitHub에서 제공하는 **CI/CD 및 자동화 플랫폼**.

리포지토리 안에 `.github/workflows/*.yml` 파일로 **워크플로우**를 정의해서

push, PR, cron 등 이벤트에 따라 **빌드/테스트/배포/기타 작업**을 자동 실행.


### 2) 특징 / 속성

- **GitHub에 내장**: 별도 서버 없이 GitHub-hosted runner 사용 가능 [GitHub Docs](https://docs.github.com/en/actions/get-started/continuous-integration?utm_source=chatgpt.com)
- **이벤트 기반**: `push`, `pull_request`, `schedule(cron)`, `workflow_dispatch(수동 실행)` 등 트리거 지원
- **Marketplace**: 수많은 오픈소스 액션들(예: `actions/checkout`, `actions/setup-node`) 조합해서 사용
- **YAML 기반 설정**: 인프라 as code 느낌으로 파이프라인 정의

### 3) 장점

- GitHub랑 **밀착 통합** → PR, Issue, Checks 탭 연동이 자연스러움
- 소규모/개인 프로젝트는 **무료 티어**로도 시작하기 쉬움
- 온프레/자체 서버에서 돌리고 싶으면 **self-hosted runner**도 지원

### 4) 단점 / 한계

- GitHub 생태계에 의존 → GitLab/Jenkins 등과 비교해 멀티-vcs 전략에는 제약
- 빌드 시간이 길어지면 **요금/시간 제한** 이슈
- 고급 시나리오(모노레포 대규모 캐싱, 복잡한 매트릭스 전략)는 설계 난이도 ↑
- Reverse Proxy

### 1) 정의

- 클라이언트(브라우저) 앞에 있는 게 아니라, **웹 서버 앞에 서 있는 프록시 서버**.

클라이언트 요청을 먼저 받고, 내부의 실제 웹 서버들로 **대신 전달·분배**한 뒤 응답을 돌려주는 중간자.


### 2) 주요 역할 / 속성

- **로드 밸런싱**: 여러 백엔드 서버로 트래픽 분산
- **캐싱**: 정적/동적 콘텐츠를 캐시해서 백엔드 부하 감소, 응답 속도 향상
- **보안 향상**: 실제 서버 IP/구조를 숨기고, 악성 트래픽 필터링, WAF 연동 등
- **SSL/TLS 종료(termination)**: HTTPS 복호화를 프록시에서 처리하고, 내부는 HTTP로 통신 가능
- **URL/경로 기반 라우팅**: `/api`는 A서비스, `/static`은 B서버 등 L7 라우팅

### 3) 장점

- 웹 서버 앞단에서 **성능/보안/운영 관리**를 한곳에 집중시킬 수 있음
- 서버 교체/증설 시, 클라이언트에서 도메인/주소를 바꿀 필요가 줄어듦
- SSL 인증서 관리, 접근 제어, 로깅 등을 중앙에서 처리

### 4) 단점 / 주의점

- 프록시 자체가 단일 장애 지점(SPOF)이 될 수 있어서 이중화 필요
- 설정이 복잡해지면 디버깅이 어려움 (특히 헤더/리다이렉트, 리버스 프록시 체인 등)
- 잘못 구성하면 오히려 레이턴시 증가 + 보안 구멍이 될 수 있음
- HTTPS

### 1) 정의

- **HTTPS (HyperText Transfer Protocol Secure)**

기존 HTTP 위에 **TLS(예전 이름 SSL)** 암호화를 입힌 프로토콜.

*“HTTP over TLS/SSL”* 이라고도 부름.

- 브라우저와 웹 서버 사이 데이터를 **암호화·무결성·서버 인증**을 제공

### 2) 특징 / 속성

- **암호화(Confidentiality)**: 제3자가 패킷을 훔쳐봐도 내용을 알 수 없음
- **무결성(Integrity)**: 전송 중 데이터가 변조되면 탐지 가능
- **서버 인증(Authentication)**: 브라우저가 서버 인증서(SSL/TLS cert)를 검증해서

진짜 해당 도메인의 서버인지 확인

- 현재는 **웹 표준** 수준: 브라우저가 HTTP 사이트에 “Not Secure” 표시하기도 함

### 3) 장점

- 로그인 정보, 개인정보, 결제 정보 등 **민감한 데이터 보호**
- SEO 측면에서도 유리 (검색 엔진이 HTTPS 사이트를 선호)
- 사용자가 “자물쇠 아이콘” 보고 심리적 신뢰 ↑

### 4) 단점 / 고려사항

- TLS 핸드셰이크/암호화로 인해 약간의 **성능 오버헤드** (요즘은 거의 무시 수준)
- 인증서 발급/갱신/관리 필요(요즘은 Let’s Encrypt + 자동 갱신으로 많이 해결)
23 changes: 23 additions & 0 deletions week10/mission/mission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
![image.png](attachment:97473f15-37f1-47c1-bfd0-9081b8058458:image.png)

![image.png](attachment:340e0844-c3aa-4c88-b32b-667086a3e1ca:image.png)

![image.png](attachment:130043fa-9f75-432f-889e-e17297cd5858:image.png)

![image.png](attachment:ae1a42a8-d8cc-48d4-84a7-0b6068108d3b:image.png)

![image.png](attachment:121a87fb-dd83-4a5a-8630-9ef656a7500b:image.png)

![image.png](attachment:4d649a07-e52e-41a9-ae4b-bfa028344211:image.png)

![image.png](attachment:2eddb007-ee13-4169-bd5f-b99d8c334837:image.png)

실습 5번까지 진행 후 Instance가 터지는 문제 발생

새로 Instance 생성 후 진행해봤지만 처음엔 잘 되다가 재접속 시 또 안됨

![image.png](attachment:c9babe35-ba54-4e34-be5c-b7fd1fee265e:image.png)

![image.png](attachment:531a2810-bd35-4fec-b890-b4c3be3bda51:image.png)

![image.png](attachment:3482c593-329f-4c5d-86ec-a2f8ce4634a2:image.png)