본문 바로가기

Web/Concept

[Web] JWT(JSON Web Token)

 

토큰 기반 인증 시스템

 

-  웹 보안의 바탕은, 인증(Authenticate) + 인가(Authorize) 로 구성된다.

 

   1)  인증(Authenticate) : 요청 사용자 식별

 

   2)  인가(Authorize) : 인증된 사용자가 보호된 리소스에 접근할 권한이 있는지 확인

 

 

  -  토큰 기반 인증 시스템은,

 

     인증을 받은 사용자에게 토큰을 발급하고

 

  -> 사용자가 서버에 요청할 때 헤더(Header)에 발급 받은 토큰을 함께 보내도록 하여 유효성을 검사한다.

 

  -  토큰 기반 인증 시스템은 서버 기반 인증 시스템과 달리, 클라이언트의 요청 시 클라이언트의 헤더에 담긴 토큰만으로 인증 정보를 확인 가능하고, 세션 관리 필요가 없어 서버 자원을 아낄 수 있다. 

 

이런, 토큰 기반 인증 시스템에 사용되는 JWT에 대해 정리한다.

 

(토큰 기반 인증 시스템과 서버 기반 인증 시스템의 차이에 대한 내용도 정리 예정.)

 

JWT(JSON Web Token)이란, 

 

1.  JWT(JSON Wen Token)의 정의

 

 -  사용자에 대한 속성 정보를 JSON 데이터 구조로 표현한 토큰

 

 -  토큰의 기본 정보, 전달할 정보, 검증되었다는 시그니처 정보를 지님

 

 -  자가 수용적(Self-Contained) 특징: 필요한 모든 정보를 자체적으로 지니고 있음

 

-> 토큰 자체를 정보로 사용하여 정보 전달

 

 

2.  JWT의 구조

 

 -  Header(헤더), Payload(페이로드), Signature(서명) 세 부분을 ' . ' (구분자)으로 구분 

 

 -  JSON 형태인 각 부분은 Base64로 인코딩 되어 표현

 

-> Base64 : 암호화된 문자열 X -> 같은 문자열에 대해 항상 같은 인코딩 문자열 반환

 

    Ex) aaaa . bbbb . cccc

         헤더    내용    서명

 

  (1)  Header(헤더)

 

    -  [alg]와 [typ]의 두 가지 정보로 구성

 

    1)  alg : Signature를 해싱하기 위한 알고리즘 지정 -> 토큰 검증 시 사용되는 Signature 부분에서 사용

        Ex) HS256(SHA256) or RSA

 

    2)  typ : 토큰의 타입을 지정 

        Ex) JWT

 

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

 

 

  (2)  Payload(페이로드)

 

    -  토큰에 담을 정보 존재

 

    -  정보의 한 '조각' = 클레임(Claim) -> Json(Ket/Value) 형태의 한 쌍으로 이루어져 있다.

 

  ->  토큰에는 여러 개의 클레임을 넣을 수 있다.

   

  [클레임의 종류]

 

    1)  등록된(Registered) 클레임

 

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

 

      -  서비스에 필요한 정보 X -> ' 토큰에 대한 정보 ' 들을 담기 위한 클레임

 

      -  선택적으로 작성 가능 및 사용 권장

 

      -  Key의 String 길이는 3

 

      -  subject는 Unique한 값 -> 사용자 이메일 사용

 

      [등록된 클레임 종류]

 

      -  iss(issuer) : 토큰 발급자

 

 

Key Value
iss(issuer) 토큰 발급자
sub(subject) 토큰 제목
aud(audience) 토큰 대상자
exp(expiration) 토큰 만료 시간 - 항상 현재 시간 이후로 설정 -> NumericDate 형식
Ex) 1480849147370
nbf(not before) 토큰 활성 날짜 - 해당 날짜 전의 토큰은 비활성화 상태
iat(issued at) 토큰 발급 시간 - 토큰 발급 이후 경과 시간(토큰의 age)
jti(JWT ID) JWT 토큰 식별자 - 중복 방지 및 일회용 토큰(Access Token) 등에 사용

 

    2)  공개(Public) 클레임

 

      -  사용자 정의 클레임

 

      -  공개용 정보를 위해 사용

 

      -  충돌 방지를 위한 이름으로 URI 포멧 사용

 

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

 

    3)   비공개(Private) 클레임

 

      -  사용자 정의 클레임

 

      -  서버와 클라이언트 사이에 임의로 지정한(필요한) 정보 저장

 

      -  공개 클레임과 달리, 중복 시 충돌 가능성이 있어 사용 시 유의해야 한다.

 

 

{ 
	"token_type": access 
}

 

  (3)  Signature(시그니처)

 

    -  서명은 토큰을 '인코딩' 하거나, '유효성을 검증' 할 때 사용하는 고유한 암호화 코드(서버만 알고 있음.)

 

    -  헤더(Header)와 페이로드(Payload)의 값을 각각 [BASE64로 인코딩]하고,

 

   -> 인코딩한 값을 [비밀 키]를 이용해, 헤더에서 정의한 알고리즘으로 [해싱]을 하고

 

   -> 이 값을 다시[ BASE64로 인코딩]하여 생성한다.

 

HEADER PAYLOAD VERIFY SIGNATURE
{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "sub": "1234567890",
  "name": "Sim",
  "iat": 1516239022
}
HMACSHA256(
    base64UrlEncode(header) + " . " +
    base64UrlEncode(payload)
) 한 값을 Base64 인코딩

 

헤더와 페이로드, 서명에 해당하는 내용이 각각 인코딩되어 JWT로 나타나는 결과값은 아래와 같다.

 

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlNpbSIsImlhdCI6MTUxNjIzOTAyMn0.1MjAckWhJVC91zNAL9lfbT0TU-5eUNKUKFujNLABmPA

 

 

JWT(JSON Web Token)은 언제 사용하는가

 

  1.  로그인

 

    -  클라이언트가 아이디 + 패스워드로 로그인 요청

 

   -> 서버가 아이디 + 패스워드 일치 여부 확인 -> 유효한 경우에, 토큰(JWT) 발급

 

   -> 클라이언트가 다음에 어떠한 요청을 할 때, 발급받은 인증 토큰을 '헤더'에 포함시켜 요청

 

   -> 서버에 요청이 오면, 헤더에 포함된 인증 토큰을 해석해 권한(인가) 확인

 

 

 

  2.  정보교류

 

    -  두 개체 사이에서 안정성 있는 정보 교환이 가능하다.

 

    -  정보가 내장되어 있어, 정보를 보낸이가 바꾸거나 조작하지 않았는지에 대한 사실을 검증 가능하다.

 

 

 

JWT(JSON Web Token)의 장단점

 

  1.  장점

 

    -  사용자 인증에 필요한 모든 정보가 토큰 자체에 포함 -> 별도의 인증 저장소가 필요없음.

 

    -  쿠키 전달 필요 X -> 쿠키 사용으로 발생하는 문제 방지 가능

 

    -  트래픽에 대한 부담이 낮음.

 

    -  REST 서비스로 제공 가능

 

    - 독립된 JWT

 

 

  2.  단점

 

    1)  데이터 증가에 따른 네트워크 부하

     

      -  모든 요청에 대해 토큰 전송 -> 토큰에 담기는 정보가 많아질수록 네트워크 부하 증가

 

    2)  Self-Contained

 

      -  토큰 자체에 모든 정보를 담고 있어, 토큰 만료 전 JWT가 탈취당하면, 서버에서 할 수 있는 것이 없다. -> 중요한 데이터를 payload에 넣어서는 안 된다.

 

    3)  무상태성(stateless)

 

      -  JWT는 상태 저장 X(연결 유지 X) -> 최초 생성 후 임의 삭제 불가 -> 만료 시간 필수 지정

 

 

 

 

 

참고

 -  https://gorokke.tistory.com/181

 -  https://mangkyu.tistory.com/56

 -  https://wildeveloperetrain.tistory.com/20