Skip to content

Readme ‐ 고민와 문제 해결

Nathan.LIU edited this page Oct 11, 2024 · 13 revisions

고민와 문제 해결

    1. serializers 사용에 대한 고민
  - 다양한 데이터 정보를 직렬화, 역직렬화해서 유지보수하기 쉽다.
  - 중복된 코딩 내용을 통일 시킬 필요가 있다.
  - 일관성 있는 응답 내용을 한곳에 정리하는 게 좋다.
  - 유효성 검사 도 serializer통해서 처리하는 게 좋다.
     의견: model를 통해 DB 접근하는 유효성 검사는 View에서 처리해주는게 맞다.
     결론: 모델의 필드 타입에 맞는지, 필수 필드가 누락되지 않았는지 등을 확인도 필요하다. 단 복잡한 유효성검사가 필요한 경우는 View에서 직접 처리하자. 

2. 테스트 대한 고민: 기능이 점점 많아지면서 테스트를 어디까지 해야하는지
  - 앱별로 테스트 추가해서 정리하자
  - 앱에 필요한 py 문서 별로 작성하자
     의견: 종복된 테스트가 많아져서 고민이다

사용자 관리(acounts.app)

1. 사용자의 권한 결정 방법
  - 모델: CustomUserManager
  - 관리자가 영상관련 정보를 조회가능한다
  - 학생은 영상관련 정보를 조회 할수 없다. 

2. 커스텀유저 필요한 이유
  - 모델: CustomUser
    - 사용자 식별 ID VS Email
	- 필수 필드 결정
	- 일부 필드 삭제

인증 기능(jwtauth.app)

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 토큰 인증상태 비저장이 필요한 대규모 애플리케이션, 모바일 클라이언트, 마이크로서비스 아키텍처, 또는 API 중심의 애플리케이션에 적합합니다.

결정

  • JWT 토큰 인증 사용하기로 결정
    • 결정 이유

      • 토큰 인증 필요한 라이버리
      • 토큰에 담은 필수 정보
      • refresh 토큰 처리 방법
        • 모델: BlacklistedToken
      • 소셜 로그인
        • 구글 로그인
        • 카카오 로그인
      1. 이슈: module 'jwt' has no attribute 'encode'
        • 원인: jwt와 PyJWT 동시 설치시 오류 발생
        • 해결: jwt와 PyJWT 삭제후 PyJWT 재설치

영상, 이미지(materials.app)

모델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의 역할이 겹친다.
  - 의견: 유지보수상 이벤트 발생시 수정하는 일 더많이 생긴다.

Course,Mission(courses.app)

모델1: Curriculum
모델2: Course
모델3: Lecture
모델4: Topic
모델5: MultipleChoiceQuestion
모델6: Assignment

payment(payments.app)

모델1: Cart
모델2: CartItem
모델3: Order
- 오더에서 Video 재생 여부를 결정하자.
모델4: OrderItem
모델5: UserBillingAddress
모델6: Payment
- materials에 UserVideo모델 추가해서, 결제여부 시청 가능한 영상 조회 하자.