창욱씨 2020. 8. 24. 23:54

JWT

JWT(Json Web Token)이란 JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token입니다. JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달합니다. 주로 회원 인증이나 정보 전달에 사용되는 JWT는 아래의 로직을 따라서 처리됩니다.


애플리케이션이 실행될 때, JWT를 static 변수와 로컬 스토리지에 저장합니다. static 변수에 저장하는 이유는 HTTP 통신을 할 때마다 JWT를 HTTP 헤더에 담아서 보내야 하는데, 이를 로컬 스토리지에서 계속 불러오면 오버헤드가 발생하기 때문입니다.
클라이언트에서 JWT를 포함해 요청을 보내면 서버는 허가된 JWT인지를 검사합니다. 또한 로그아웃을 할 경우 로컬 스토리지에 저장된 JWT 데이터를 제거합니다.

JWT의 특징

수 많은 프로그래밍 언어에서 지원

JWT는 C, Java, Python 등 대부분의 주류 프로그래밍 언어에서 지원합니다.

자가 수용적

JWT는 필요한 모든 정보를 자체적으로 지니고 있습니다. JWT 시스템에서 발급된 토큰은 토큰에 대한 기본 정보, 전달할 정보 그리고 토큰이 검증되었다는 것을 증명해주는 signature를 포함하고 있습니다.

쉽게 전달 가능

JWT는 두 개체 사이에서 손쉽게 전달되 수 있습니다. 웹 서버의 경우 HTTP 헤더에 넣어서 전달할 수도 있고, URL의 파라미터로 전달할 수도 있습니다.

JWT의 형태

 JWT는 "." 을 구분자로 3가지의 문자열로 되어 있습니다. 아래와 같이 이루어져 있습니다.

헤더(Header)

Header는 두 가지의 정보를 지니고 있습니다.

  • typ: 토큰의 타입을 지정합니다.
  • alg: 해싱 알고리즘을 지정합니다. 해싱 알고리즘으로는 보통 SHA256 혹은 RSA가 사용되며, 이 알고리즘은 토큰을 검증할 때 사용되는 signature 부분에서 사용됩니다.
    {
      "typ": "JWT",
      "alg": "HS256"
    }

정보(Payload)

Payload 부분에는 토큰에 담을 정보가 들어있습니다. 여기에 담는 정보의 한 '조각'을 클레임(claim)이라 부르고 이는 name/value의 한 쌍으로 이루어져 있습니다. 토큰에는 여러 개의 클레임들을 넣을 수 있습니다.
클레임의 종류는 다음과 같이 크게 세 분류로 나뉘어져 있습니다.

  • 등록된 클레임
  • 공개 클레임
  • 비공개 클레임

등록된 클레임

등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기 위하여 이름이 이미 정해진 클레임들입니다. 등록된 클레임의 사용은 모두 선택적이며, 이에 포함된 클레임 이름들은 다음과 같습니다.

  • iss: 토큰 발급자
  • sub: 토큰 제목
  • aud: 토큰 대상자
  • exp: 토큰의 만료 시간
  • nbf: 토큰의 활성 날자
  • iat: 토큰이 발급된 시가
  • jti: JWT의 고유 식별자

공개 클레임

공개 클레임들은 충돌이 방지된 이름을 가지고 있어야 합니다. 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 짓습니다.

{
    "https://kchanguk.tistory.com": true
}

비공개 클레임

등록된 클레임도 아니고, 공개된 클레임들도 아닙니다. 양 측간에(클라이언트 <-> 서버) 협의하에 사용되는 클레임 이름들입니다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할 때 유의해야 합니다.
{
"username": "velopert"
}

서명(signature)

서명은 헤더의 인코딩 값과 정보의 인코딩 값을 합친 후, 주어진 비밀키로 해쉬를 하여 새엇ㅇ합니다.

JWT 단점 및 고려사항

Self-contained

토큰 자체에 정보를 담고 있기 때문에 보안에 문제가 생길 수 있습니다.

토큰 길이

토큰의 페이로드에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.

Payload 인코딩

페이로드 자체는 암호화된 것이 아니라, BASE64로 인코딩 된 것입니다. 중간에 페이로드를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 페이로드에 중요 데이터를 넣지 않아야 합니다.

Stateless

JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능합니다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 합니다.

Tore Token

토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 합니다.

참조: https://velopert.com/2389

728x90