개발하는 체대생

[Server] JWT(JSON Web Token)이란? 본문

카테고리 없음

[Server] JWT(JSON Web Token)이란?

개발하는체대생

JWT 란? 

JWT(JSON Web Token)은 JSON 포멧을 이용하여 사용자에 대한 속성을 저장하는 Claim(Claim이란? 사용자에 대한 프로퍼디나 속성을 의미)기반의 Web Token이다.

즉, JWT는 인증하는데 필요한 정보들을 암호화 시켜놓은 JSON 토큰을 의미한다.

이미지 출처 : https://mangkyu.tistory.com/56

애플리케이션이 실행될 대, JWT를 static 변수와 로컬 스토리지에 저장하게 된다.

static 변수에 저장되는 이유는 -> HTTP 통신을 할 때 마다 JWT를 HTTP헤더에 담아서 보내야 하는데 이를 로컬 스토리지에서 계속 불러오면 오버헤드가 발생하기 때문이다.

(로그인 시)클라이언트에서 JWT를 포함해 요청을 보내면 서버는 허가된 JWT인지 검사를 한다.

(로그아웃 시)로컬 스토리지에 저장된 JWT 데이터를 삭제한다.

 

JWT의 특징

- 토큰 자체에 사용자 권한이나 서비스를 사용하기 위한 정보를 담고 있다.(-> 장점이 될 수도 단점이 될 수도)

- 토큰 자체에 정보를 담고 있기 때문에 별도의 저장소가 필요없다.

- 토큰 자체에 정보를 담고 있기 때문에 탈취 당하면 위험하다(->Playload  자체가 암호화 된 것이 아니라 Base64 Url로 인코딩 된 것 이기 때문에 decoding 하면 데이터를 볼 수 있다. 그래서 JWE로 암호화하거나 Playload에 중요한 정보를 넣지 말아야 한다.)

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

- session과 다르게 서버가 아닌 클라이언트에 저장된다.(-> 메모리, 스토리지 등을 통해 세선을 관리하는 서버의 부담을 덜 수 있음)

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

 

 

JWT의 구조

JWT는 1)Header(헤더) 2)Playload(내용) 3)Signature(서명) 이렇게 3가지로 구성된다.

각 요소는 . 으로  구분된다.

이미지 출처 : https://velopert.com/2389

1)Header(헤더)

Header에는 2가지 종류가 있는데 '타입의 종류(typ)'와 '해싱 알고리즘의 종류(alg)' 가 담겨있다.

타입 : 타입에서는 토큰의 타입을 지정하는데 위에서 언급했던 'JWT' 이다.

해싱 알고리즘 : 해싱 알고리즘으로는 HMAC SHA256 혹은 RSA 가 사용되고, 이 알고리즘은 마지막에 토큰을 검증할 때 사용되는 Signature 부분에서 사용된다.(이 곳에서 암호화 하는 것이 아니고 Signature에서 암호화 하기 위한 알고리즘을 지정만 해주는 것임!!)

 

2)Playload(내용)

Playload 부분에는 토큰에 담을 정보들(사용자 권한 정보와 데이터)이 들어가 있고 JSON(name/value)형태로 한 쌍으로 이루어져 들어가 있다. 이때 정보들의 한 조각을 Claim이라고 부른다. Claim의 종류는 등록된 클레임(Registered Claim), 공개 클레임(Public Claim), 비공개 클레임(Private Claim)과 같이 3분류로 나눠져 있다.

간단하게 3가지 클레임에 대해 설명하자면

  (1)등록된 클레임(Registered Claim)

   - 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터

  • iss: 토큰 발급자 (issuer)
  • sub: 토큰 제목 (subject)
  • aud: 토큰 대상자 (audience)
  • exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야한다.
  • nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념이다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
  • iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단 할 수 있다.
  • jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용된다. 일회용 토큰에 사용하면 유용하다.

 

  (2)공개 클레임(Public Claim)

   - 사용자 정의 클레임으로, 공개용 정보를 위해 사용, 충돌이 방지된 이름을 가지고 있어야함.(충돌 방지를 하기 위해서 클레임 이름을 URL 형식으로 지어야함.)

 

  (3)비공개 클레임(Private Claim)

   - 사용자 정의 클레임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다.(양측(=클라이언트와 서버)간의 협의하에 사용되는 클레임 이름을 사용함.)

 

3)Signature(서명)

Signature에서는 Header에 명시된 해시함수를 적용하고 Playload(내용)의 값들을 Base64 URL-safe Encode(=Base64 Encode를 할 때 URL에서 오류없이 사용하도록 +,/를 각각 -,_로 표현한 것)를 하고, 개인키(Private Key)로 서명한 전자서명이 담겨있다.

 

Comments