[Django] - jwt

오동훈·2023년 7월 6일
0

Django

목록 보기
23/23

1. JWT란

JWT(Json Web Token)는 당사자 간에 정보를 Json 객체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준입니다.

간단한 형태의 JWT는 .을 구분자로 세 부분으로 구성되어 있습니다.

1. Header

Header는 일반적으로 토큰 유형(JWT)과 사용 중인 서명 알고리즘으로 총 2개의 정보를 지니고 있습니다.

  1. typ - 토큰의 타입
  2. alg - 해싱 알고리즘

JWT를 사용할 목적이므로 토큰의 타입 typ은 JWT입니다.
JWT 해싱 알고리즘은 보통 HMAC SHA256 or RSA가 사용되며 해당 알고리즘은 암복호화에 사용됩니다.

그래서 Header 부분에는 보통 아래와 같이 사용하게 됩니다.

{
  "typ": "JWT",
  "alg": "HS256"
}

그런 다음 이 JSON은 Base64Url로 인코딩되어 JWT의 첫 번째 부분을 구성합니다.

2. Payload

payload 부분에는 토큰에 담을 정보(클레임)를 입력하는 부분입니다. 클레임은 데이터에 대한 설명이자, key-value 형태로 이루어져 있습니다.

클레임의 종류에는 3가지의 유형이 있습니다.

  1. 등록된 클레임
  2. 공개 클레임
  3. 비공개 클레임

등록된 클레임

등록된 클레임에는 서비스에 필요한 정보들이 아닌, 토큰에 대한 정보를 담기 위해 이미 정해져 있는 클레임들입니다. 여기에 있는 정보를 모두 사용해도 되고 일부만 사용해도 무관합니다. 기타 다른 클레임도 많지만 이들 중 일부는 아래와 같습니다.

  • iss : 토큰 발급자 (issuer)
  • sub : 토큰 제목 (subject)
  • aud : 토큰 대상자 (audience)
  • exp : 토큰 만료시간 (expiration) - 시간은 NumericDate 형식(Unix time)으로 되어있어야 합니다. ex)1480849147370
  • iat : 토큰이 발급된 시간(issued at) - 이 값을 사용해 토큰의 시간이 얼마나 지났는지 확인 가능합니다.

JWT가 간결하기 때문에 클레임 이름을 3글자로 작성하는 걸 권고하고 있습니다.

공개 클레임

공개 클레임은 JWT를 사용하는 사람들이 마음대로 정의할 수 있습니다. 그러나 다른 사람들과 겹치면 안되기때문에 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 작성해야합니다.

{
    "https://velopert.com/jwt_claims/is_admin": true
}

비공개 클레임

비공개 클레임은 클라이언트와 서버 간 합의하에 사용되는 클레임 이름들입니다.

{
    "user_id": 1
}

예시 Payload

위에 설명들을 기반으로 Payload를 다음과 같이 작성할 수 있습니다.

payload = {
    "user_id": 1,
    "expired": 1485271295000,
    "iat": 1485270000000, 
}

그런 다음 payload는 Base64Url로 인코딩되어 JWT의 두 번째 부분을 형성합니다.

해당 부분은 누구나 읽을 수 있기 때문에 JWT의 Header와 Payload에 비밀 정보를 입력하지 말아야 합니다.

3. signature

다음은 서명(signature)입니다. 헤더의 인코딩 값과, 정보의 인코딩 값을 합친 후 주어진 비밀키로 해쉬를 하여 생성합니다.

예를 들어 HMAC SHA256 알고리즘을 사용하려는 경우 서명은 다음과 같은 방식으로 생성됩니다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

이렇게 되면 Header와 Payload가 인코딩되고 secret 암호로 서명된 JWT를 볼 수 있습니다.

JWT 디버거를 이용해 상세하게 확인해 볼 수 있습니다.

2. JWT 사용법

인증에서 사용자가 자격 증명을 이용해 성공적으로 로그인하게 되면 JWT를 받을 수 있습니다. ex). 카카오 로그인

사용자가 보호된 영역에 엑세스하려고 할 때마다 사용자는 일반적으로 Authorization 헤더 내 Bearer 스키마를 사용해 보내야 합니다. 헤더의 내용은 다음과 같습니다.

Authorization: Bearer <token>

3. JWT 장점

JWT에는 다음과 같은 장점이 있습니다.

  1. JWT는 사용자 인증에 필요한 모든 정보를 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요하지 않습니다.
  2. JSON 코드 언어로 생성된 토큰은 용량이 작기 때문에 두 엔티티 사이에서 매우 빠르게 전달됩니다.
  3. 쿠키를 사용하지 않으므로, 관련한 보안 취약점이 사라집니다.

4. JWT 단점

장점이 있으면 단점이 있기 마련입니다. JWT는 아래와 같은 단점을 지니고 있습니다.

  1. JWT 자체에 정보를 담고 있어 양날의 검이 될 수 있습니다.
  2. JWT는 단일 키를 사용합니다. 따라서 키가 유출되면 시스템 전체가 위험에 노출될 수 있습니다.
  3. 토큰에 저장하는 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.

참고자료 📩
JWT 공식문서
RFC 7519 JSON Web Token (JWT) 개방형 표준
기타 다른 클레임
JWT 디버거
URI 형식

profile
삽질의 기록들🐥

0개의 댓글