IT/Django

Django 에서 토큰 기반 인증 과 JWT 기반 인증

mmww 2024. 9. 27. 10:06

Django 로고

 

최근 파이널 프로젝트에서 account 앱을 맡게되었는데 그 중 토큰 기반인증과 JWT 인증을 더 깊게 알게되었습니다.
해당 개념을 정리 및 공유 하면 좋을것 같아 글을 작성해 보았습니다.

Django REST Framework(DRF)에서 제공하는 기본적인 토큰 기반 인증(Token Authentication)JWT(JSON Web Token) 기반 인증은 둘 다 토큰을 사용하여 사용자 인증을 수행하는 방법이지만, 여러 가지 차이점이 있습니다. 이 차이점은 토큰의 발급 방식, 토큰의 구조, 보안성, 확장성 등의 요소에서 나타납니다. 각 방식의 동작 방식과 장단점을 더 상세하게 분석해 보겠습니다.

1. 토큰 발급 방식 및 관리

1.1 DRF의 기본 토큰 인증 (Token Authentication)

  • 발급 방식: Django REST Framework의 기본 TokenAuthentication은 로그인 시 서버에서 고유한 토큰을 생성하고, 이를 서버의 데이터베이스에 저장합니다.
  • 토큰 관리: 이 토큰은 서버에 저장된 상태에서 서버가 클라이언트로부터 받은 토큰을 매번 데이터베이스에서 확인해 인증을 수행합니다. 서버가 해당 토큰을 저장하고 있어야 하므로 토큰 관리의 책임은 서버에 있습니다.

예시:

  • 사용자가 로그인하면 서버는 데이터베이스에 유니크한 토큰을 생성하여 저장하고, 클라이언트에게 반환합니다. 이후 클라이언트는 이 토큰을 Authorization 헤더에 추가하여 서버에 요청을 보냅니다.

장점:

  • 토큰을 서버에서 관리하기 때문에 토큰을 서버 측에서 강제로 폐기할 수 있습니다. 즉, 필요할 때 언제든지 토큰을 무효화할 수 있습니다.
  • 토큰이 유효한지에 대한 검증은 서버 데이터베이스에서 이뤄지므로 안전합니다.

단점:

  • 서버가 모든 토큰을 저장하고 관리해야 하므로, 서버 측 리소스가 소모됩니다. 특히 사용자가 많거나 확장성이 요구되는 환경에서는 성능에 부담이 될 수 있습니다.
  • 데이터베이스를 매번 조회해야 하므로 인증 과정에서의 성능 저하가 발생할 수 있습니다.

1.2 JWT 기반 인증 (JWT Authentication)

  • 발급 방식: JWT는 서버에서 생성되며, 클라이언트에게 발급됩니다. 서버는 토큰을 저장하지 않습니다. JWT는 클라이언트 측에서 보관되고, 요청할 때마다 클라이언트가 서버에 토큰을 전달합니다. 토큰에는 사용자의 정보와 만료 시간 등의 정보가 인코딩되어 있습니다.
  • 토큰 관리: JWT는 자체적으로 유효성 검증이 가능하며, 서버는 토큰을 데이터베이스에 저장하거나 별도로 관리할 필요가 없습니다. 서버는 단순히 토큰의 서명(Signature)을 검증하고, 클레임을 확인하여 인증을 수행합니다.

장점:

  • 서버에 상태를 저장하지 않는 무상태(stateless) 방식이므로 확장성이 뛰어납니다. 여러 서버에서 토큰을 검증할 수 있으므로, 분산 환경에 적합합니다.
  • 토큰에 만료 시간(exp)을 지정할 수 있어 자동으로 만료되도록 설정할 수 있습니다. 클라이언트는 갱신을 통해 새로운 토큰을 발급받을 수 있습니다.

단점:

  • JWT는 서버에서 토큰을 폐기하기 어렵습니다. 서버가 토큰을 저장하지 않기 때문에 한 번 발급된 토큰은 만료 시간 전까지는 유효합니다. 이 문제를 해결하기 위해 서버에서 블랙리스트 관리 또는 발급 시점을 검증하는 방법을 사용할 수 있습니다.
  • 클라이언트에 토큰이 저장되기 때문에 XSS(크로스 사이트 스크립팅) 공격에 취약할 수 있습니다. 따라서 보안 조치(예: HTTPS, HttpOnly 쿠키 설정 등)가 중요합니다.

2. 토큰의 구조 및 보안성

2.1 DRF의 기본 토큰

  • 토큰 구조: DRF의 기본 토큰은 서버에서 고유한 임의의 문자열을 생성하여 클라이언트에게 제공하는 방식입니다. 이 토큰은 서버의 데이터베이스에 저장되어 있으며, 별도의 구조적 의미를 지니지 않습니다.
  • 보안성: 서버가 모든 토큰을 관리하고 있어, 토큰이 유출되면 바로 무효화할 수 있습니다. 하지만 토큰 자체에는 별도의 정보가 담겨 있지 않기 때문에 이로 인한 보안 위협은 적습니다.

2.2 JWT

  • 토큰 구조: JWT는 세 부분으로 구성됩니다:
    1. Header: 토큰의 타입과 해싱 알고리즘 정보
    2. Payload: 사용자 정보 및 클레임 (예: 사용자 ID, 발급 시간, 만료 시간)
    3. Signature: 토큰의 무결성을 검증하기 위한 서명
    Payload 부분에는 사용자와 관련된 정보가 담겨 있으며, 이 정보는 암호화되지 않고 Base64 URL-safe로 인코딩됩니다. 따라서 누구나 디코딩하여 Payload를 확인할 수 있습니다. 이 때문에 민감한 정보는 포함하지 않도록 주의해야 합니다.
  • 보안성: JWT는 서버에서 관리되지 않으므로 토큰이 유출되면 만료 시간 전까지는 이를 사용할 수 있습니다. 또한, XSS 공격에 취약할 수 있기 때문에 보안 조치가 매우 중요합니다. 그러나 JWT는 서명을 통해 토큰의 무결성을 검증할 수 있으며, 이로 인해 클라이언트가 토큰을 변조할 수 없습니다.

3. 토큰 만료 및 갱신

3.1 DRF의 기본 토큰

  • 기본 토큰은 자체적으로 만료 시간이 없기 때문에, 서버에서 수동으로 만료 또는 갱신을 처리해야 합니다. 사용자가 로그아웃하거나 관리자가 토큰을 강제로 폐기하지 않는 이상, 토큰은 계속 유효합니다.

3.2 JWT

  • JWT는 발급 시 토큰에 만료 시간을 포함할 수 있습니다. exp 클레임을 사용하여 토큰의 만료 시간을 지정하고, 토큰이 만료되면 클라이언트는 새로운 토큰을 발급받아야 합니다.
  • 보통 Access TokenRefresh Token을 함께 사용하여, Access Token은 짧은 만료 시간을 가지고, Refresh Token은 이를 갱신하는 용도로 사용됩니다. 이를 통해 보안성을 강화할 수 있습니다.

4. 사용 사례 및 확장성

4.1 DRF의 기본 토큰

  • 사용 사례: 소규모 웹 애플리케이션이나 사용자 수가 적은 프로젝트에 적합합니다. 서버에서 모든 토큰을 관리하기 때문에 확장성에 한계가 있으며, 많은 트래픽을 처리하는 시스템에서는 성능 문제가 발생할 수 있습니다.
  • 확장성: 단일 서버 또는 작은 규모의 서버 클러스터에서 사용하기에 적합하며, 서버 간 세션 동기화 또는 외부 저장소를 사용하지 않는다면 확장성에 제약이 있습니다.

4.2 JWT

  • 사용 사례: 대규모 분산 시스템 또는 클라우드 환경에서 주로 사용됩니다. 서버가 상태를 저장하지 않으므로 서버 간의 토큰 동기화 문제가 발생하지 않습니다. 모바일 앱, SPA(Single Page Application) 등의 무상태 환경에서 매우 유용합니다.
  • 확장성: 서버의 상태와 무관하게 토큰을 발급하고 검증할 수 있기 때문에 매우 높은 확장성을 자랑합니다. 수백, 수천 대의 서버가 분산된 환경에서도 무리 없이 사용 가능합니다.

5. 장단점 요약

특징 DRF 기본 토큰 인증 JWT 기반 인증
토큰 저장 서버에서 저장 클라이언트에서 저장
토큰 폐기 서버에서 강제 폐기 가능 서버 측 폐기 어려움, 블랙리스트 필요
확장성 서버 자원 사용, 확장성 제한 무상태, 확장성 우수
보안성 토큰 자체에는 정보 없음 Payload에 정보 담김, XSS 취약 가능성
토큰 갱신 수동 관리 Access Token과 Refresh Token 사용 가능
토큰 검증 성능 데이터베이스 조회 필요 자체적으로 서명 검증 가능, DB 조회 불필요
적용 사례 소규모 웹 애플리케이션 대규모 분산 시스템, 모바일, 클라우드 서비스

결론

Django REST Framework 의 두가지 토큰 인증 방법에 대해서 알아보았습니다.
두가지의 방법의 장단점을 잘 숙지하여 적절하게 사용하셨으면 합니다.

'IT > Django' 카테고리의 다른 글

Django에서 사용하는 다양한 파일구조  (0) 2024.10.11