JWT 소개

1. JWT란?

  • JSON Web Token
  • 서버와 클라이언트 간 HTTP Request의 Header나 URI 쿼리 파라미터에 토큰을 사용하여 안전하게 정보를 주고 받을 수 있게 해준다.
  • HMAC 알고리즘을 사용하여 비밀키나 RSA를 이용한 Public Key / Private Key 쌍으로 서명 가능.


2. JWT의 구조


1. Header

{
  "typ": "JWT",
  "alg": "HS256"
}
  • Header에는 두 가지 정보가 들어간다.

    • type : 토큰의 타입을 지정 (대부분 JWT)
    • alg: 토큰에 사용한 알고리즘(HS256, HS512, RS256, ES256등의 알고리즘을 사용할 수 있다.)


2. Payload

{
    "iss": "doosil",							# 등록된 클레임
    "exp": "1434290400000",						# 등록된 클레임
    "username": "doosil",						# 비공개 클레임
    "https://doosil87.github.io/": true			# 공개 클레임
}
  • 실제 토큰의 Body로 JWT는 이를 디코딩해서 바로 값을 확인 할 수 있기 때문에 DB 조회가 필요 없이 사용자 아이디 등을 여기에 담아 놓는다.
  • 여기에 담겨 있는 정보 한 조각들을 클레임(claim)이라 부르며 세 가지 종류가 있다.
    1. 등록된 클레임(registered)
      • iss: 토큰 발급자(issure)
      • sub: Claim의 Subject로 토큰이 갖는 문맥을 의미 (subject)
      • aud: 토큰 대상자(audience)
      • exp: 만료시간(Expiration Time)으로 지난 토큰은 거절
      • nbf: Not Before로 이 시간 이전에는 토큰을 처리하지 않음
      • iat: 토큰 발급 시간(Iuused At)
      • jti: JWT ID로 토큰 식별자
    2. 공개 클레임(public)
      • 충돌을 방지하기 위해서 공개된 이름이며, URI 형식으로 짓는 것이 보통이다.
    3. 비공개 클레임 (private)
      • 서버와 클라이언트가 협의로 사용하는 이름


3. Signature

  • 앞의 헤더와 Payload는 암호화를 한 것이 아니라 단순히 JSON문자열을 base64로 인코딩한 것 뿐이다. 때문에 누구나 이를 디코딩하면 JSON 내용을 확인할 수 있다. 이 토큰을 위변조 되었는지 검증하는 부분이 Signature 부분이다.
  • 헤더와 Payload 사이를 마침표로 이어 붙이고 헤더에 적힌 알고리즘 HS256 즉, HMAC SHA-256으로 인코딩하면 JWT 토큰의 세 번쨰 부분인 Signautre를 만들고 이를 Payload 뒤에 .으로 붙인다.


3. JWT의 디버거


4. JWT Process


5. JWT 정리

  • JWT의 가장 큰 특징은 토큰 자체가 데이터를 가지고 있다는 점이다.

    일반적인 토큰의 흐름은 API 요청 시에 DB에 저장 된 토큰을 보고 만료시간이나 유효한 사용자인지 확인한다. 요청마다 DB를 조회하는 것은 비용이 든다.

    JWT의 경우 토큰을 받아서 서명으로 유효한 토큰인지 검증 한 뒤 클레임 셋을 디코딩하여 데이터를 열어본다.즉, DB나 캐시를 조회할 필요없이 사용자를 확인하고 정보를 조회할 수 있다.

  • JWT의 주의점

    • 토큰의 길이가 다소 길다는 문제가 있다.
    • 토큰을 강제로 만료시킬 방법이 없다. 토큰 발급 시 해당 토큰이 유효한 조건이 결정되므로 로그아웃하더라도 해당 토큰을 클라이언트에게서 제거하는 것 뿐이다. 어떤 다른 누군가가 토큰을 탈취한다면 해당 토큰은 만료시간까지 유효하다.