반응형
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
Tags
- 실시간 통신
- 자기관리
- 성공에 대한 거짓말
- HTML
- 원씽
- 카뷰 수익 인증
- 도서 원씽
- ppt 다이어그램
- 위드굿즈 굿즈샵
- 위드굿즈
- 카카오뷰 성장
- 웹기초
- 30일 글쓰기
- ppt 도형 색
- git 협업하기
- 엑셀 프린트하기
- 책 원씽
- 엑셀 기초 함수
- express.js 환경 셋팅
- Axios 라이브러리
- 이석증
- 성공비법
- Git 팀 작업
- 카카오뷰N잡
- 카카오뷰 수익
- 카카오뷰 부업
- CSS
- 카카오뷰 탭이동
- 카카오뷰 온라인 수익화
- 카카오뷰 초보
Archives
- Today
- Total
김데이의 개발공부
[ WIL ] Day 62~64 - 중급 프로젝트 : ERD / Prisma Schema / OAuth 본문
코드잇 Node.js(BE) 부트 캠프/WIL (Weekly I Learn) 📚
[ WIL ] Day 62~64 - 중급 프로젝트 : ERD / Prisma Schema / OAuth
theday365 2025. 12. 28. 19:37반응형
🚀 이번 주 핵심 📚
1. 중급 프로젝트 진행 : 주요 작업 내용
- 프로젝트 주제 선정
- 협업 규칙 설정 : 프로젝트 문서 - 노션 / 코드 공유 - 깃허브 등등
- 프로젝트 전체 ERD 정리
- 정리 한 ERD를 바탕으로 Prisma Schema 작성
2. 프로젝트 작업에 필요한 개념 공부
- ERD 작업
- DB Diagram 서비스 이용
- 각 테이블 별 고유 필드 / 관계형 필드 / enum 설정
- Prisma Schema 작업
- 실무에서 보편적으로 사용하는 네이밍 방식으로 설계
- 하나의 테이블에서 여러 필드를 관계형으로 불러오는 방식 적용
- 유저 인증 절차
- 일반 회원 가입 방식 : 토큰을 활용한 User 가입 / 로그인 방식
- Oauth : 자사 서버에 직접 가입/로그인 하지 않고 제 3자를 통해 권한을 위임 받는 방식
- Passport : 유저의 인증&인가 과정을 좀 더 쉽게 구현하기 위한 라이브러리. 특히, 다양한 플랫폼의 Oauth 인증&인가가 가능함
🤔 어려웠던 개념, 다시 공부하기 📑
1. 실무에서 많이 쓰는 ERD 작업 플로우
1️⃣ 도메인 / 요구사항 정리
- 사용자가 어떤 일을 하고, 어떤 데이터가 쌓이는지 정리
- 엔티티 = 서비스에서 '독립적으로 존재하고, 저장돼야 하는 명사',
ID가 있고, 여러 개 존재하고, 관계를 맺고, 나중에 따로 관리하고 싶은 대상
⇒ 엔티티들 추출
2️⃣ 전체 테이블(엔티티) 네이밍
- users, products, orders, order_items 같은 큰 덩어리 작업
3️⃣ 테이블별 PK 설계
- id, 복합키(2개 이상의 id 또는 unique를 결합) 설계
- PK에 적용할 uuid, ai(Auto-Increment) 결정
4️⃣ 관계 정의 (FK, 1:1 / 1:N / N:M)
- 테이블 간의 관계 정의 및 관계에 사용 할 필드 설정
- N:M 관계의 경우 중간 테이블 추가 생성
5️⃣ 나머지 필드 설계
- 일반 컬럼을 작성하며 해당 컬럼의 속성(string, int, enum, Boolean 등) 설정
- 컬럼의 nullable 여부 설정
- id 값 이 외에 사용할 unique / index 확인
2. Prisma Schema 작업
[ Prisma Schema sample ]
model Order {
id Int @id @default(autoincrement())
userId Int @map("user_id")
status OrderStatus @default(PENDING)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id])
@@map("orders")
}
enum OrderStatus {
PENDING
PAID
CANCELED
}
1️⃣ Model 이름
- PascalCase, 단수형
- 예시 : User, Product, OrderItem 등
- JS/TS 코드에서 쓰기 좋은 명사형 사용
- DB 테이블 이름
- @@map() 사용하여 model 최 하단에 재선언
- snake_case, 복수형
- 예시 : users, products, order_items 등
- SQL에서 가독성 좋아지고, 시스템 친화적
2️⃣ 필드 이름
- camelCase
- 예시 : name, userId, status, createdAt
- JS/TS 친화적인 방식
- DB 테이블 이름
- @map() 사용하며, 한 단어로 끝나지 않은 필드 값에만 적용
- snake_case, 복수형
- 예시 : user_id, created_at 등 / name, status 같은 한 단어에는 적용하지 않음
- SQL에서 가독성 좋아지고, 시스템 친화적
3️⃣ Enum 이름 / 값
- 이름 : PascalCase / 값 : SCREAMING_SNAKE_CASE
- 이름 예시 : OrderStatus, Category 등
값 예시 : PENDING, CANCELED 등
4️⃣ 다중 관계형 설정
- 같은 모델을 두 번 참조하면 @relation 작성 시 이름을 넣어 연결 해 주어야 함
- @relation 이름은 ‘의미 기준’으로 작성
- 양쪽 모델 모두 컬럼을 각각 따로 선언해야 함(하나의 @relation에 합쳐서 선언하면 안됨)
model User {
id Int @id @default(autoincrement())
name String
// 관계 (역방향)
orders Order[] @relation("OrderUser")
deliveryOrders Order[] @relation("OrderAddress")
@@map("users")
}
model Order {
id Int @id @default(autoincrement())
// 주문자
userId Int @map("user_id")
user User @relation("OrderUser", fields: [userId], references: [id])
// 배송지
addressUserId Int @map("address_user_id")
addressUser User @relation("OrderAddress", fields: [addressUserId], references: [id] )
createdAt DateTime @default(now()) @map("created_at")
@@map("orders")
}
3. 유저 인증 절차
- 사용자가 자사 홈페이지에 들어와서 로그인을 진행할 때, 구글을 선택함.
- 그럼 자사 클라이언트(=브라우저)가 서버(=백엔드)를 거치지 않고, 바로 구글 Oauth 인증 서버로 요청을 보내는데
이때 자사 서버의 정보(client id = 구글 Oauth 서버에 등록 된 자사 서버 id)와 콜백 url 등을 담아서 보냄
[ 요청 URL 예시 ]
GET https://accounts.google.com/o/oauth2/v2/auth
?client_id=YOUR_CLIENT_ID : 우리 앱 식별자
&redirect_uri=https%3A%2F%2Fapi.myapp.com%2Fauth%2Fgoogle%2Fcallback : 인증 끝나면 돌아 올 주소
&response_type=code : 응답은 코드로 전달 해 달라 요청
&scope=openid%20email%20profile%20https%3A%2F%2Fhttp://www.googleapis.com%2Fauth%2Fcalendar.readonly : 필요한 권한 범위
&access_type=offline
&prompt=consent
&state=RANDOM_CSRF_TOKEN - 구글 Oauth 서버가 위 내용을 보고, 사용자가 접속 할 수 있는 "구글 로그인 창"을 클라이언트(=브라우저)에게 보냄
- 사용자는 자신의 정보를 입력하고 "로그인"을 누름
- 구글 Oauth서버가 "Authorize 코드"를 클라이언트(=브라우저)로 보냄
[ 응답 URL 예시]
GET https://api.myapp.com/auth/google/callback
?code=4%2F0AbCdEfGhIjKlMn... : Authorization Code
&state=RANDOM_CSRF_TOKEN
&scope=openid%20email%20profile%20https%3A%2F%2Fhttp://www.googleapis.com%2Fauth%2Fcalendar.readonly - 클라이언트는 받은 코드로 추가 작업을 할 수 없으므로, 자사 서버(=백엔드)에게 인증 코드(= Authorize 코드)를 줌
( = 이 과정이 일상으로 비교 했을 때, 우리가 공공기관 같은데 접속할 때 본인인증 하면 핸드폰으로 인증 번호가 전달 되서, 사람이 공공기관 사이트에 인증번호를 입력하게 됨. "핸드폰=클라이언트"는 필요한 인증번호를 받아주는 역할일 뿐, 결국 그걸 가지고 어떤 시도를 하는건 "사람=서버" 임) - 자사 서버(=백엔드)는 Authorize 코드와 함께 "자사 서버 인증 정보(client id, secret 등 구글 Oauth에 등록 된 서버의 로그인 정보)" 를 보내서 구글 Oauth에 등록 된 서버임을 증명함.
[ 요청 URL 예시]
POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded
code=4%2F0AbCdEfGhIjKlMn... : Authorization Code
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET
redirect_uri=https://api.myapp.com/auth/google/callback
grant_type=authorization_code - 구글 Oauth 서버에서는 해당 정보를 확인 한 뒤 권한 영역(scope)과 Access 토큰, 유저 id (id_token) 등을 담아서 자사서버로 보내 줌. 자사 서버(=백엔드)는 받은 정보를 DB에 저장 해 두고, 클라이언트에게는 자사 Access 토큰 / refresh 토큰을 만들어 보내 주면서 접속 성공을 알림
[ 응답 JSON 예시 ]
{
"access_token": "ya29.a0ARrdaM...", : 구글 Oauth Access 토큰
"expires_in": 3599,
"refresh_token": "1//0gL... ", : 조건에 따라 보내주거나 생략함
"scope": "openid email profile https://www.googleapis.com/auth/calendar.readonly",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIs..." : 구글에서 사용하는 User id
} - 사용자가 자사 홈페이지를 이용하다가 구글 캘린더에 저장/정보 불러오기 할 일이 생기면 클라이언트가 자사에서 생성한 Access 토큰을 사용해 자사 서버(=백엔드)로 요청을 보내면,
자사 서버(=백엔드)가 클라이언트에게 받은 Access 토큰을 이용해 구글 OAuth Access 토큰을 찾음
(구글 Oauth서버가 보내주면, 로그인 성공 할 때 서버가 DB에 유저 정보와 함께 보관하고 있었음) - 서버에 보관한 구글 Oauth Access 토큰을 가지고 자사 서버(=백엔드)가 구글 캘린더 서버로 접속 요청을 보냄.
[ 요청 URL 예시]
GET https://www.googleapis.com/calendar/v3/calendars/primary/events
Authorization: Bearer ya29.a0ARrdaM... : 구글 Oauth Access 토큰 - 구글 캘린더에서 Access 토큰 검증을 하여 요청 한 내용을 실행!
[응답 JSON 예시]
{
"items": [
{
"id": "abc123",
"summary": "회의",
"start": { "dateTime": "2025-12-29T10:00:00+09:00" },
"end": { "dateTime": "2025-12-29T11:00:00+09:00" }
}
]
}

다른 팀에 비해 팀원이 조금 적은 편이라 각자의 역할이 중요한데,
내 실력이 많이 뒤떨어 지는 느낌이 들어서
휴일과 주말을 반납하고 열심히 공부 했다.. 📖✍️
근데도 너무 어려운 유저 인증 절차 😭
아무리 파고 또 파도 그 순간에는 이해 되지만 뒤돌아 서면 리셋 되버리니..
어떡하면 좋아..ㅠㅠ
반응형
'코드잇 Node.js(BE) 부트 캠프 > WIL (Weekly I Learn) 📚' 카테고리의 다른 글
| [ WIL ] Day 65~74 - 중급 프로젝트 : Prisma ORM 정리 (1) | 2026.01.10 |
|---|---|
| [ WIL ] (도저히 이해가 안가서 GPT와 만든) 비동기 처리 특집!🤖 (0) | 2025.09.28 |
| [ week 1 ] 웹 기초 지식 한번에 훑어보기 (1) | 2025.09.23 |