어 나 갱수.

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

카테고리 없음

[JWT] JWT란? (JSON Web Token)

김경수 2023. 7. 26. 11:08
728x90

JWT에 대해 알아보기 전에 "토큰 기반 인증"과 "서버 기반 인증"에 대해 알아보자.

서버 기반 인증

세션 기반의 인증 시스템이다. 서버 측에서 사용자들의 정보를 기억하기 위해 세션을 유지하는데, 이는 메모리, 디스크, 데이터베이스 등을 통해 관리한다. 클라이언트로부터 요청을 받으면 클라이언트의 상태 정보를 저장하여 유지해야 하므로 Stateful 한 구조를 가진다.

 

[인증 방식]

1. 사용자가 로그인 시 올바른 사용자임을 확인하고, 고유한 세션 ID 값을 부여해 세션 저장소에 저장하고 클라이언트에게 발급해 준다.

2. 클라이언트는 세션 ID를 받아 쿠키에 저장하고, 인증이 필요한 요청마다 쿠키에 세션 ID를 담아 헤더에 보낸다.

3. 서버에서는 쿠키를 받아 세션 저장소와 비교해 올바른 요청인지 확인한다.

4. 인증이 완료되고 서버는 요청에 응답한다.

토큰 기반 인증

이러한 단점을 극복하기 위해 "토큰 기반 인증 시스템"이 나왔다. 인증받은 사용자에게 토큰을 발급해 주고, 서버에 요청을 할 때 HTTP 헤더에 토큰을 함께 보내 인증받은 사용자(유효성 검사)인지 확인한다. 서버 기반 인증 시스템과 달리 사용자의 인증 정보를 서버에 저장하지 않고 클라이언트의 요청으로만 인가를 처리하므로 Stateless 한 구조를 가진다.

 

[ 인증 방식 ] 

1. 유저가 아이디와 비밀번호로 로그인을 합니다.

2. 서버 측에서 해당 계정정보를 검증합니다.

3. 계정정보가 정확하다면, 서버 측에서 유저에게 signed 토큰을 발급해 줍니다.

4. 클라이언트 측에서 전달받은 토큰을 저장해 두고, 서버에 요청을 할 때마다, 해당 토큰을 함께 서버에 전달합니다.

5. 서버는 토큰을 검증하고, 요청에 응답합니다.

웹서버에서 토큰을 서버에 전달할 때에는, HTTP 요청의 헤더에 토큰값을 포함시켜서 전달합니다.

JWT 란?

JSON Web Token의 약어이며, 사전적 정의는 다음과 같습니다.

JWT는 선택적 서명 및 선택적 암호화를 사용하여 데이터를 만들기 위한 인터넷 표준으로, 페이로드는 몇몇 claim을 assert 처리하는 JSON을 보관하고 있다. - 위키백과

JWT의 탄생 배경

전통적인 세션 인증 방식의 경우에는 Stateful 방식입니다. 즉, 서버에서 세션에 대한 상태를 알고 있다는 뜻입니다. 그렇기에 매 요청마다 서버와 통신을 해야 하고, 이는 곧 많은 트래픽 발생시켜 서버 부하의 원인이 되기도 합니다. JWT는 이러한 문제점들을 해결하기 위해 등장했습니다. Stateless인 것이 특징입니다. 토큰 안에 미리 인증에 필요한 정보들을 넣어둠으로써 매 요청마다 서버와 통신할 필요가 없게 되었습니다.

JWT의 장점

  • JWT의 주요한 이점은 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요 없다는 것입니다. 
  • 분산 마이크로 서비스 환경에서 중앙 집중식 인증 서버와 데이터베이스에 의존하지 않는 쉬운 인증 및 인가 방법을 제공합니다.

JWT의 구조

JWT는 세 파트로 나누어지며, 각 파트를 점(. )으로 구분한다. 각 순서대로 헤더(header), 페이로드(payload), 서명(signature)으로 구성되고, JSON 형태인 각 부분은 BASE64로 인코딩 되어 표현된다.

헤더

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

서명 생성을 위해 어떤 알고리즘을 사용할지 식별하는 부분입니다. alg에서는 알고리즘 방식을 지정할 수 있고 서명 및 토큰 검증과 생성에 사용됩니다. type에서는 토큰의 타입을 정할 수 있습니다.

페이로드

{
    "iss" : "https://leffept.tistory.com",
    "aud" : "https://leffept,.tistory.com",
    "iat" : 1356999254,
    "exp" : 1399999999,
    "name" : "leffe",
    "location" : "seoul"
}

일련의 클레임을 포함합니다. 토큰의 목적에 따라서 이곳에 여러 가지 정보를 추가할 수 있습니다. 

그러나 민감한 정보는 포함하지 않는 게 좋습니다. JWT 토큰은 디코딩을 통해 들어있는 정보를 확인하는 것이 매우 쉽습니다.

등록된 클레임(Registered Claim) 

등록된 클레임은 토큰 정보를 표현하기 위해 이름이 이미 정해진 종류의 데이터이다. 등록된 클레임의 사용은 모두 선택적이지만, 사용할 것을 권장한다.

iss : 토큰 발급자 (issuer)

sub : 토큰 제목 (subject)

aud : 토큰 대상자 (audience)

exp : 토큰의 만료시간 (expiraton) : NumericDate 형식으로 되어 있어야 한다.

nbf : 토큰 활성 날짜(not before) :  이 날이 지나기 전의 토큰은 활성화되지 않는다.

iat : 토큰 발급 시간(issued at) : 토큰 발급 이후의 경과 시간을 알 수 있다.

jti : JWT 고유 식별자(JWT ID) : 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용한다.

서명

HMAC-SNA256(
    secret,
    base64urlEncoding(header) + '.' +
    base64urlEncoding(payload)
)

서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드입니다. 

서명은 위에서 만든 헤더(Header)와 페이로드(Payload)의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀 키를 이용해 헤더(Header)에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로 인코딩하여 생성합니다. 

 

이렇게 만든 해쉬를, base64 형태로 나타내면 됩니다 (문자열을 인코딩하는 게 아닌 hex → base64 인코딩을 해야 합니다)

 

생성된 토 크을 https://jwt.io/의 디버거에 붙여 넣어보세요 (JWT.IO 는 브라우저 상에서 JWT 토큰을 검증하고 생성할 수 있게 해주는 디버거 서비스입니다)

위의 사진과 같이 토큰에 대한 정보가 나옵니다.

마무리

오늘은 JWT란 무엇이며, 그 구조는 어떻게 이루어져 있는지 알아보았습니다.

글 읽어 주셔서 감사합니다!!

 


Reference

728x90