최근 파이널 프로젝트에서 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는 세 부분으로 구성됩니다:
- Header: 토큰의 타입과 해싱 알고리즘 정보
- Payload: 사용자 정보 및 클레임 (예: 사용자 ID, 발급 시간, 만료 시간)
- Signature: 토큰의 무결성을 검증하기 위한 서명
- 보안성: JWT는 서버에서 관리되지 않으므로 토큰이 유출되면 만료 시간 전까지는 이를 사용할 수 있습니다. 또한, XSS 공격에 취약할 수 있기 때문에 보안 조치가 매우 중요합니다. 그러나 JWT는 서명을 통해 토큰의 무결성을 검증할 수 있으며, 이로 인해 클라이언트가 토큰을 변조할 수 없습니다.
3. 토큰 만료 및 갱신
3.1 DRF의 기본 토큰
- 기본 토큰은 자체적으로 만료 시간이 없기 때문에, 서버에서 수동으로 만료 또는 갱신을 처리해야 합니다. 사용자가 로그아웃하거나 관리자가 토큰을 강제로 폐기하지 않는 이상, 토큰은 계속 유효합니다.
3.2 JWT
- JWT는 발급 시 토큰에 만료 시간을 포함할 수 있습니다.
exp
클레임을 사용하여 토큰의 만료 시간을 지정하고, 토큰이 만료되면 클라이언트는 새로운 토큰을 발급받아야 합니다. - 보통 Access Token과 Refresh 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 |
---|