-
Notifications
You must be signed in to change notification settings - Fork 1
Readme ‐ 고민와 문제 해결
Nathan.LIU edited this page Oct 11, 2024
·
13 revisions
1. serializers 사용에 대한 고민
- 다양한 데이터 정보를 직렬화, 역직렬화해서 유지보수하기 쉽다.
- 중복된 코딩 내용을 통일 시킬 필요가 있다.
- 일관성 있는 응답 내용을 한곳에 정리하는 게 좋다.
- 유효성 검사 도 serializer통해서 처리하는 게 좋다.
의견: model를 통해 DB 접근하는 유효성 검사는 View에서 처리해주는게 맞다.
결론: 모델의 필드 타입에 맞는지, 필수 필드가 누락되지 않았는지 등을 확인도 필요하다. 단 복잡한 유효성검사가 필요한 경우는 View에서 직접 처리하자.
2. 테스트 대한 고민: 기능이 점점 많아지면서 테스트를 어디까지 해야하는지
- 앱별로 테스트 추가해서 정리하자
- 앱에 필요한 py 문서 별로 작성하자
의견: 종복된 테스트가 많아져서 고민이다
1. 사용자의 권한 결정 방법
- 모델: CustomUserManager
- 관리자가 영상관련 정보를 조회가능한다
- 학생은 영상관련 정보를 조회 할수 없다.
2. 커스텀유저 필요한 이유
- 모델: CustomUser
- 사용자 식별 ID VS Email
- 필수 필드 결정
- 일부 필드 삭제
1. 인증 문제:
- 세션인증 VS 토큰 인증
### **a. 세션 인증 (Session Authentication)**
**세션 인증**은 전통적인 인증 방식으로, 서버가 사용자 로그인 시 인증 정보를 서버 메모리나 데이터베이스에 저장하고, 클라이언트와 서버 간의 모든 요청에서 이를 확인하는 방식입니다.
#### **작동 방식**
1. 사용자가 로그인하면 서버는 **세션 ID**를 생성하고, 이를 서버 측(예: 데이터베이스)에 저장합니다.
2. 서버는 이 세션 ID를 **쿠키**에 담아 클라이언트에게 전달합니다.
3. 이후 클라이언트는 각 요청마다 이 쿠키를 서버로 다시 전송합니다.
4. 서버는 세션 ID를 확인하여 사용자 상태를 인증합니다.
#### **장점**
- **서버가 상태를 관리**: 서버에서 세션 데이터를 저장하고 관리하므로, 사용자가 로그아웃하거나 세션이 만료되면 서버에서 이를 즉시 처리할 수 있습니다.
- **안전성**: 세션 데이터는 서버에 저장되므로, 민감한 사용자 정보가 클라이언트에 노출되지 않습니다.
- **기본적인 브라우저 지원**: 세션은 쿠키와 함께 사용되므로, 대부분의 브라우저와 쉽게 연동됩니다.
#### **단점**
- **서버 부하**: 각 사용자마다 세션을 서버가 관리해야 하므로, 많은 사용자가 접속할수록 서버의 메모리와 리소스를 소모합니다.
- **스케일링 어려움**: 서버가 상태를 유지해야 하기 때문에, 여러 대의 서버를 사용할 때 세션 동기화 문제가 발생할 수 있습니다. 분산 서버 환경에서는 세션 관리가 까다로울 수 있습니다.
- **CSRF 공격 가능성**: 세션 인증은 쿠키 기반이므로, CSRF(Cross-Site Request Forgery) 공격에 취약할 수 있습니다.
---
### **b. JWT 토큰 인증 (JWT Authentication)**
**JWT (JSON Web Token)**은 상태 비저장 인증 방식으로, 클라이언트가 로그인 후 서버에서 발급한 토큰을 클라이언트 측에 저장하고 요청마다 이를 서버로 보내어 인증하는 방식입니다.
#### **작동 방식**
1. 사용자가 로그인하면 서버는 **JWT 토큰**을 생성하고 클라이언트에게 전달합니다.
2. 이 토큰은 클라이언트(주로 브라우저의 LocalStorage나 SessionStorage)에 저장됩니다.
3. 이후 클라이언트는 요청 시마다 이 JWT를 **Authorization 헤더**에 담아 서버로 전송합니다.
4. 서버는 토큰을 확인하여 사용자를 인증합니다. JWT는 **서명**되어 있으므로 서버는 토큰이 변조되지 않았는지 확인할 수 있습니다.
#### **장점**
- **상태 비저장(Stateless)**: 서버는 상태를 유지할 필요가 없고, 세션을 저장하지 않으므로 서버 리소스 사용이 적습니다.
- **확장성**: 분산 시스템에서도 세션 동기화가 필요 없으므로, 여러 서버 간 확장이 용이합니다.
- **보안**: JWT는 서명이 포함된 토큰이므로, 변조를 방지할 수 있습니다. 또한 클라이언트가 직접 토큰을 관리하므로, CSRF 공격의 위험이 줄어듭니다(하지만 XSS에는 취약할 수 있습니다).
- **다른 서비스와의 통합**: JWT는 여러 서비스 간 인증을 쉽게 통합할 수 있어 마이크로서비스 아키텍처에서 유리합니다.
#### **단점**
- **토큰 만료 관리 필요**: JWT는 상태 비저장이므로, 로그아웃 시 서버에서 토큰을 무효화하는 게 어렵습니다. 일반적으로 만료 시간을 설정하여 토큰의 유효성을 관리하지만, 즉각적인 토큰 무효화는 복잡할 수 있습니다.
- **안전한 저장소 필요**: 클라이언트에 토큰을 저장하는 방식이므로, 브라우저의 LocalStorage나 SessionStorage에 저장할 때 **XSS 공격**에 취약할 수 있습니다.
- **토큰 크기**: JWT는 세션보다 크기(정보를 많이 담을 경우)가 클 수 있으며, 각 요청마다 이 토큰을 전송해야 하므로 네트워크 부하가 증가할 수 있습니다.
---
### **비교 요약**
세션 인증(Session Authentication) | JWT 토큰 인증(JWT Authentication) | |
---|---|---|
서버 상태 | 서버가 세션 상태를 유지 | 상태 비저장, 서버는 세션을 유지하지 않음 |
저장 위치 | 서버 메모리나 DB | 클라이언트 측(LocalStorage, Cookie 등) |
보안 취약점 | CSRF 취약 가능 | XSS 취약 가능 |
확장성 | 서버 간 세션 동기화 필요 | 서버 간 확장에 유리 |
로그아웃 처리 | 세션을 삭제하여 쉽게 처리 | 즉각적인 토큰 무효화는 복잡 |
서명 검증 | 서버 측에서 세션 검증 | 클라이언트가 서명된 토큰 전송, 서버에서 검증 |
### **결정**
- **JWT 토큰 인증** 사용하기로 결정
결정 이유
1. 서버 부하 최소화.
2. 인증에 필요한 정보의 량이 작아서 네트워크 부하 증가 우려가 작다.
3. 토큰 만료는 토큰 수명와 Blacklist 모델 통해서 관리 합니다.
4. 현재 대부분 서비스가 마이크로서비스 아키텍처 적용해서, 좋은 개발 경험이 될 수 있다.
5. XSS와 같은 보안 위협에 대비하여 Refresh토큰을 Secure Cookies로 보냅니다.
- 토큰 인증 필요한 라이버리
PyJWT: JWT 토큰을 사용하여 인증 시스템을 구축하는 데 유용한 라이브러리입니다. 사용법이 간단하면서도 보안 기능을 제공하기 때문에, API 서버나 마이크로서비스와 같은 환경에서 널리 사용됩니다.
- 토큰에 담은 필수 정보
- "user_id"
- 권한 "is_staff" "is_superuser"
- 발급 시간 "iat"
- 필수 "nickname" "email"
- 특수 "image" - 편의성
- 수명 "exp"
- refresh 토큰 처리 방법 RTR
**RTR(Refresh Token Rotation)**는 만료된 JWT 토큰을 처리하고 새 토큰을 발급하는 방식으로, 보안을 강화하는 데 중요한 방법 중 하나입니다. JWT 인증에서 **토큰 만료 처리**와 **토큰 갱신**이 중요한 이슈인데, 이 문제를 해결하는 하나의 전략이 **Refresh Token Rotation**입니다.
### **Refresh Token Rotation(RTR) 개념**
RTR은 **갱신 토큰(Refresh Token)**를 한 번 사용할 때마다 새로운 갱신 토큰을 발급하고, 이전 갱신 토큰을 폐기하는 방식입니다. 이를 통해 만료된 토큰을 안전하게 관리할 수 있고, 보안을 강화할 수 있습니다.
### **기본 원리**
1. **Access Token**: 만료 시간이 짧은 토큰으로, 사용자는 이 토큰을 통해 요청을 인증합니다.
2. **Refresh Token**: 만료 시간이 긴 토큰으로, Access Token이 만료되었을 때 새로운 Access Token를 발급받는 데 사용됩니다.
3. **토큰 순환**: 기존의 Refresh Token를 사용할 때마다 새로운 Refresh Token이 발급되며, 사용된 기존의 Refresh Token은 즉시 무효화됩니다.
### **작동 방식**
1. **사용자 로그인 시**:
- 서버는 Access Token과 Refresh Token를 함께 발급합니다.
- Access Token은 클라이언트가 API 요청 시 인증하는 데 사용되고, Refresh Token은 클라이언트 측에 저장됩니다.
2. **Access Token 만료 시**:
- 클라이언트는 만료된 Access Token과 Refresh Token를 서버로 전송합니다.
- 서버는 Refresh Token이 유효한지 확인하고, 유효하면 새로운 Access Token과 Refresh Token를 발급합니다.
- 이때, **기존의 Refresh Token은 폐기**되고 **새로운 Refresh Token**이 발급됩니다.
3. **Refresh Token 도난 방지**:
- 이전에 발급된 Refresh Token이 노출되어 악의적인 사용자가 이를 사용하려고 할 때, 해당 토큰은 이미 무효화되었기 때문에 재사용이 불가능합니다. 이를 통해 보안을 강화할 수 있습니다.
### **RTR 사용 시 장점**
1. **보안성 강화**: Refresh Token를 한 번 사용할 때마다 새로운 토큰을 발급하여, 도난된 토큰의 재사용을 방지할 수 있습니다.
2. **토큰 탈취 위험 감소**: 누군가 Refresh Token를 탈취해도, 그 토큰은 이미 만료된 상태일 가능성이 크기 때문에 보안 위협을 줄일 수 있습니다.
3. **긴 세션 유지**: 짧은 Access Token의 수명을 유지하면서도, Refresh Token를 통해 사용자가 지속적으로 인증 상태를 유지할 수 있습니다.
### **RTR 사용 시 고려 사항**
1. **클라이언트 측 보안**: Refresh Token은 클라이언트에서 안전하게 관리되어야 합니다. LocalStorage 대신 **HTTPOnly 쿠키** 등을 사용하는 것이 보안을 강화하는 데 도움이 됩니다.
2. **서버 측 저장소**: Rotation 전략을 사용하면, 이전 Refresh Token이 폐기되었는지 확인하기 위해 서버에서 관리할 필요가 있습니다. **Blacklist 모델** 또는 **Whitelist 모델**를 사용하여 발급된 Refresh Token를 관리해야 합니다.
### **JWT와 Refresh Token 관리 흐름**
1. **로그인**:
- 사용자 로그인 시 Access Token과 Refresh Token 발급.
2. **Access Token 만료**:
- Access Token이 만료되면, 클라이언트는 Refresh Token를 사용하여 새 Access Token를 요청.
3. **Refresh Token Rotation**:
- 서버는 Refresh Token를 검증한 후, 새로운 Access Token과 새로운 Refresh Token을 발급. 기존의 Refresh Token은 더 이상 사용할 수 없도록 폐기.
4. **Refresh Token 관리**:
- Blacklist를 사용하여 폐기된 Refresh Token이 다시 사용되지 않도록 관리.
- 모델 추가: BlacklistedToken
-
소셜 로그인 - 구글 로그인 - 카카오 로그인
-
이슈 - module 'jwt' has no attribute 'encode' - 원인: jwt와 PyJWT 동시 설치시 오류 발생 - 해결: jwt와 PyJWT 삭제후 PyJWT 재설치
모델1: Image
이슈: 이미지 업로드 문제
https://github.com/weaverse-techtide/weaverse-backend/issues/167
모델2: Video
모델3: VideoEventDate
모델 관계 고민
의견: 결제된 강의 영상만 영상 시청
유저 : Video = 1 : N
Video : VideoEventDate = 1 : N
의견: 권한 설정와 별개로 유저와 Video 는 각각 독립 적인 관계
- 유저 : VideoEventDate = 1 : N
- Video : VideoEventDate = 1 : N
추가 - WatchHistory 모델 추가 고민
- 목적: 유저가 Video 모델와 VideoEventDate 관리하자.
- 의견: VideoEventDate와 WatchHistory의 역할이 겹친다.
- 의견: 유지보수상 이벤트 발생시 수정하는 일 더많이 생긴다.
모델1: Curriculum
모델2: Course
모델3: Lecture
모델4: Topic
모델5: MultipleChoiceQuestion
모델6: Assignment
모델1: Cart
모델2: CartItem
모델3: Order
- 오더에서 Video 재생 여부를 결정하자.
모델4: OrderItem
모델5: UserBillingAddress
모델6: Payment
- materials에 UserVideo모델 추가해서, 결제여부 시청 가능한 영상 조회 하자.
Footer