JWT 와 Session

 

  • 세션은 서버 측에서 인증을 마친 사용자 정보를 가지고 있는 것
  • JWT 는 인증을 마치고 권한에 대한 정보를 클라이언트 측에서 암호화된 텍스트 형태로 가지고 있는 것

 

왜 JWT 인가?

 

  • 헤더와 페이로드를 가지고 서명 필드를 생성하기 때문에 데이터 변조 후 재전송을 막을 수 있음
  • 세션 기반 시스템은 분산 / 클러스터형 애플리케이션 사용하기 어려운 반면, 클라이언트 측에서 인가에 필요한 정보를 가지고 있기 때문에 확장성이 용이

 

JWT 란?

 

Json Web Token (RFC 7519)의 약자로서, 2010 년 12월 28일 처음 게시되었음

JWT의 이점은 다음과 같다.

  • 메타 데이터를 포함할 수 있음
  • OAuth 2와 호환 됨
  • 만료를 제어할 수 있음
  • json 형식으로 데이터가 전송 됨

 

JWT 예제

 

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E

다음과 같은 모양을 하고 있다.

헤더.페이로드.서명

 

 

JWT 헤더

 

JWT를 검증하는데 필요한 정보를 가진 JSON 객체로 Base64 URL-Safe 인코딩 되어 있다.

{
    "alg": "ES256",
    "kid": "Key ID"
}

alg 는 서명시 사용하는 알고리즘을 명시한 부분이고 kid 는 서명시 사용하는 키(Public/Private Key)를 식별하는 값이다.

이 객체를 문자열로 직렬화 한 뒤, UTF-8과 Base64 URL-Safe로 인코딩하면 다음과 같은 헤더를 생성할 수 있다.

 

 

표현식

Base64URLSafe(UTF-8('{"alg": "ES256","kid": "Key ID"}'))

인코딩 후

eyJhbGciOiJFUzI1NiIsImtpZCI6IktleSBJRCJ9

 

JWT 페이로드

 

JWT 의 내용을 담고있는 부분이다.

페이로드에 있는 속성들을 클레임 셋(Claim Set) 이라고 부른다.

 

JWT 의 내용을 담고있는 부분이다.

페이로드에 있는 속성들을 클레임 셋(Claim Set) 이라고 부른다.

클레임 셋은 JWT에 대한 내용(토큰 생성자 (클라이언트)의 정보, 생성 일시 등등)이나 클라이언트와 서버간 주고 받기로 한 값들로 구성이 된다.

 

표현식

Base64URLSafe('{"iss": "jinho.shin","iat": "1586364327"}')

인코딩 후

eyJpYXQiOjE1ODYzNjQzMjcsImlzcyI6ImppbmhvLnNoaW4ifQ

 

 

JWT 서명

 

점(.)을 구분자로 해서 헤더와 페이로드를 합친 문자열을 서명한 값이다.

alg에 정의된 알고리즘과 서버의 비밀 키를 이용해 생성하고 Base64 URL-Safe로 인코딩한다.

 

표현식

HMACSHA256(Base64URLSafe(header) + "." + Base64URLSafe(payload), KEY);

인코딩 후

MEQCIBSOVBBsCeZ_8vHulOvspJVFU3GADhyCHyzMiBFVyS3qAiB7Tm_MEXi2kLusOBpanIrcs2NVq24uuVDgH71M_fIQGg

 

 

JWT

 

점을 구분자로 해서 헤더, 페이로드, 서명을 합치면 JWT 가 완성된다.

eyJhbGciOiJFUzI1NiIsImtpZCI6IktleSBJRCJ9.eyJpYXQiOjE1ODYzNjQzMjcsImlzcyI6ImppbmhvLn
NoaW4ifQ.eyJhbGciOiJFUzI1NiIsImtpZCI6IktleSBJRC9.eyJpYXQiOjE1ODYzNjQzMjcsImlzcyI6Imp
pbmhvLnNoaW4ifQ.MEQCIBSOVBBsCeZ_8vHulOvspJVFU3GADhyCHyzMiBFVyS3qAiB7Tm_ME
Xi2kLusOBpanIrcs2NVq24uuVDgH71M_fIQGg

이렇게 완성된 JWT는 헤더의 alg, kid 속성과 공개 키를 이용해 검증할 수 있다.

서명 검증이 성공하면 JWT 의 모든 내용을 신뢰할 수 있게 되고 페이로드 값으로 접근 제어나 원하는 처리를 할 수 있게 된다.

 

JWT 사용시 주의 점

 

  • 공격자에 의해서 토큰이 중간에서 가로채기를 당하거나 도난을 당하는 경우 시스템에 대한 접근 권한을 얻기 위해 악용이 될 수 있다.
  • CSRF, HttpOnly, SameSite, Secure, cookie prefixes 와 같은 보안 설정이 갖추어져야 합니다.

인증에 쿠키를 기반으로 사용할 때, 서버에 어떠한 요청을 보내면 자동으로 쿠키가 전달 되기 때문에 쿠키 기반은 CSRF 공격에 취약하다.

따라서 localStorage 에 토큰을 보관할 수 있으나 이는 XSS 공격에 취약하게 됩니다.

따라서 적절한 보안 솔루션을 마련해야 합니다.

 

JWT 를 사용한 클라이언트 요청

 

클라이언트가 JWT 를 이용해서 서버에 요청을 보낼 때 다음과 같은 형식으로 보내집니다.

Authorization: <type> <credentials>

JWT 와 함께 많이 언급 되는 "bearer" 란 용어는 type 에 해당하는 한 종류이다.

이 type 에 따라서 우리는 토큰을 다르게 처리합니다.

 

 

Authorization type 정리

 

Bearer

JWT 혹은 OAuth에 대한 토큰을 사용한다. (RFC 6750)

Digest

서버에서 난수 데이터 문자열을 클라이언트에 보낸다. 클라이언트는 사용자 정보와 nonce를 포함하는 해시값을 사용하여 응답한다 (RFC 7616)

HOBA

전자 서명 기반 인증 (RFC 7486)

Mutual

암호를 이용한 클라이언트-서버 상호 인증 (draft-ietf-httpauth-mutual)

AWS4-HMAC-SHA256

AWS 전자 서명 기반 인증

 

 


출처

https://velog.io/@lre12/Kit-Pay-JWT

 

[Kit-Pay] JWT

프로젝트에서 사용한 JWT

velog.io

 

'개발 > 이론' 카테고리의 다른 글

Redis 기본 개념  (0) 2021.12.08
OSI7계층/네트워크 통신의 7계층  (0) 2020.11.29