Programming/Spring Boot

JWT 토큰 기반 인증 시스템 (JSON Web Token)

Jan92 2021. 8. 12. 00:26

JWT

Spring Boot + Security + JWT + Redis 를 기본으로한 RESTful API를 구현하기로 계획하며 토큰 기반 인증 시스템 JWT에 대해서 다시 한번 정리합니다.

 

 

토큰 기반 인증 시스템이란,

 

먼저 웹 보안은 요청하는 사용자를 식별하는 인증 (Authenticate)와 인증된 사용자가 보호된 리소스에 접근할 권한이 있는지 확인하는 인가 (Authorize) 가 바탕이 됩니다.

 

토큰(Token) 기반 인증 시스템은 인증을 받은 사용자에게 토큰을 발급하고, 사용자가 서버에 요청을 할 때 헤더(Header)에 발급 받은 토큰을 함께 보내도록 하여 유효성을 검사합니다.

* 사용자의 정보를 세션에 계속 유지해야 하는 서버 기반 인증 시스템과 달리 연결을 유지하지 않는 stateless 구조를 갖습니다.

 

덕분에 시스템에서는 클라이언트가 요청했을 때 클라이언트의 헤더에 담긴 토큰만으로 인증 정보를 확인할 수 있고, 세션 관리가 필요 없어 서버 자원을 아낄 수 있습니다.

 

 


 

header, payload, signature

 

JWT(JSON Web Token)이란,

 

속성 정보를 JSON 데이터 구조로 표현한 토큰입니다.

토큰의 기본 정보, 전달할 정보, 검증되었다는 시그니처 정보 등을 지니고 있으며, 필요한 모든 정보를 자체적으로 지니고 있는 자가 수용적 (Self-contained) 특징이 있습니다.

JWT는 Java 뿐만 아니라 C, C++, C#, R, Python, PHP, Javascript, Ruby, Go, Swift 등 대부분의 언어에서 지원됩니다.

 

 

Json Web Token

JWT는 헤더(Header), 페이로드(Payload), 서명(Signature) 세 부분을 ' . ' 으로 구분하는 구조입니다.

 

Header,

먼저 헤더는 JWT를 어떻게 검증하는가에 대한 내용을 담고 있습니다.

typ은 토큰의 타입 정보에 대한 정보를 담고 있고, alg는 어떤 해싱 알고리즘을 쓰는지에 대한 정보가 담겨 있습니다.

(JWT, HMAC SHA256)

 

Payload,

페이로드에는 JWT의 정보가 담겨있습니다. 담겨있는 정보(속성)들을 클레임 셋(Claim Set)이라고 하며, 각 정보의 조각은 클레임(Claim)이라고 합니다. 이 클레임은 name, value 쌍으로 이뤄져 있습니다.

payload에는 여러 개의 클레임을 넣을 수 있는데, 클레임의 종류는 등록된 클레임(registered), 공개 클레임(public), 비공개 클레임 (private)으로 세분화 됩니다.

 

- 등록된 클레임

: 서비스에 필요한 정보들이 아닌 토큰에 대한 정보들을 담기 위한 클레임입니다.

토큰 발급자(iss), 토큰 제목(sub), 토큰 만료시간(exp), 토큰이 발급된 시간(nbf)등의 선택적 옵션들이 있습니다.

 

- 공개 클레임

: 사용자 정의 클레임으로 공개용 정보를 위해 사용합니다. 충돌을 방지하기 위한 이름을 가지고 있어야 하기 때문에 URI 포맷을 이용합니다.

 

- 비공개 클레임

: 클라이언트와 서버간의 필요한 정보를 담은 클레임입니다.

 

Signature,

시그니처는 헤더(header)와 페이로드(payload)를 합친 문자열을 서명한 값입니다. 헤더의 alg에 정의된 알고리즘과 시그니처의 secret key를 이용하여 생성하고 Base64로 인코딩합니다.

 

 

이렇게 생성된 Header, Payload, Signature 세 부분을 합치면 JWT가 됩니다.

 

 


 

그리고 이렇게 생성된 JWT는 다음과 같이 사용됩니다.

 

 

1. 클라이언트가 아이디와 패스워드로 로그인을 요청합니다.

(이때는 헤더에 토큰 정보가 없기 때문에 권한이 필요한 서비스에는 접근할 수 없습니다.)

 

2. 서버가 아이디와 패스워드 일치 여부를 확인합니다. 유효한 경우 토큰 (JWT)를 발급힙니다.

 

3. 클라이언트가 다음 요청을 할 때, 발급 받은 인증 토큰을 헤더에 포함시켜 요청을 합니다.

 

4. 서버는 요청이 왔을 때 헤더에 포함된 인증 토큰을 해석하여 권한(인가)를 확인합니다.

 

 


 

JSON Web Token의 장점,

 

- 웹, 앱 간의 쿠키, 세션 처리에 효율적입니다.

: 데스크탑 뿐만 아니라 스마트폰, 태블릿 같은 모바일 기기의 접근도 생각한다면 다양한 디바이스에서 하나로 사용할 수 있는 JWT가 효율적입니다.

 

- 쿠키의 취약점이 사라집니다.

: 보안성 쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 사라집니다. 대신 토큰의 취약점이 발생합니다.

 

JSON Web Token의 단점,

 

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

: 모든 요청에 대해 토큰이 전송되기 때문에 토큰에 담기는 정보가 많을 수록 네트워크 부하가 증가합니다. 

 

- 자가수용적 (self-containde)

: 토큰 자체에 모든 정보를 담고 있기 때문에 토큰 만료 전 JWT가 탈취당한다면 서버에서는 할 수 있는 것이 없습니다. 그렇기 때문에 중요 데이터를 payload에 넣는 것은 위험할 수 있습니다.

 

- 무상태성 (stateless)

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

 

 

 

 

참고자료

https://meetup.toast.com/posts/239

https://covenant.tistory.com/201