REST API 서비스와 Stateless 아키텍처
- 앞의 7장까지는 세션을 활용하는 브라우저 웹 기반 서비스에 대해서 시큐리티를 어떻게 활용하는지를 살펴봤다.
- 지금부터는 SPA(SIngle Page Apllication), 안드로이드/아이폰 모바일 앱 등을 위해 API를 제공하는 API 서버에서 시큐리티를 어떻게 활용할 수 있는지를 알아야한다.
- 앞서 REST API에 대한 이해가 필요하다 !
JWT 알기 전 기본 HTTP 지식
REST API ?
- API 서비스 개발을 위한 가장 일반적인 접근 방법이다. (사실상 표준 !)
- 엄격하게 REST API 디자인 원칙을 따르는 것은 쉽지 않다.
- 통장적으로 REST API로 부르고 있다 — 사회적 통념을 따르자.
- Java, Python, Go 등 다양한 언어로 풍부한 레퍼런스가 존재한다. - 구현이 쉬움 !
- HTTP 프로토콜 기반만 따르면 어떤 기술이든 응용이 가능하다.(XML, JSON)
- 앞에서 알아본 3-Tier Archiecture 구조와 REST API 서비스 궁합이 좋다.
- 3-Tier Archietecture의 장점 대부분은 REST API 서비스를 개발 및 운영을 할때 유요하다.
- REST API 서비스에서 Session을 꼭 써야 하는 가에 대해서는 서비스 성격에 따라 고민이 필요하다.

Stateful vs Statelsess
- Stateful 아키텍처의 장단점
- 세션을 사용하고 있다면 Stateful 하다고 할 수 있다.
- 앞서 살펴 본 것처럼 수평확장(Scale-Out) 과정이 쉽지 않다. - Session Cluster 반드시 필요
- Session Cluster의 장애 또는 성능 병목이 서비스 전체에 큰 영향을 줄 수 있다.
- 단일 사용자의 다중 로그인 컨트롤, 사용자 유효성 체크, 강제 로그아웃 기능 구현이 쉽다.
- Stateless 아키텍처의 장단점
- Session을 전혀 사용하지 않아야함 - 사실 HTTP 프로토콜 자체가 Stateless 이기 때문.
- 수평확장이 매우 쉽다 - Session Cluster 필요가 없다.
- 단일 사용자의 다중 로그인 컨트롤, 사용자 유효성 체크, 강제 로그아웃 기능 구현이 어렵다.
- 무엇보다 완전한 Stateless 아키텍처 기반으로 유의미한 서비스 개발이 어렵다.
- 완전한 Stateless 서비스는 정적 리소스(html, css, js, image)를 서비스 하는데 적합하다. - AWS S3
- 서버는 어떤식으로는 사용자를 식별할 수 있어야 한다.(단, session 금지)
JWT란 무엇인가?
JWT(Json Web Token)
JWT는 Stateless 상태를 유지하며, 서버에서 사용자를 식별할 수 있는 수단을 제공한다.
- 서버에서 사용자가 성공적으로 인증되면 JWT를 반환한다.
- 클라이언트는 JWT를 로컬 영역에 저장하고, 이후 서버에 요청을 보낼 때 JWT를 HTTP 헤더에 포함시킨다.
- 서버는 클라이언트가 전달한 JWT를 통해 사용자를 식별할 수 있다.

JWT의 개요
- JSON 포맷을 사용하여 데이터를 만들기 위한 웹 표준(RFC 7519)
- JWT는 자체적으로 필요한 모든 정보를 지니고 있다.(self-contained)
- 토큰에 대한 메타정보(토큰타입, 사용된 해시 알고리즘)
- 사용자 정의 데이터
- 토큰 유효성 검증을 위한 데이터
- 인터넷상에서 쉽게 전달할 수 있다.
- URL-Safe 텍스트로 구성되기 때문에 HTTP 프로토콜의 어느 위치에든 들어갈 수 있다.(보통 HTTP 헤더에 들어감)
- 위변조 검증이 가능하다.
- 토큰이 위변조 되지 않았음을 증명하는 서명을 포함한다.
JWT의 구조
- Header, Payload, Signature 세 부분으로 구성된다.
- Header, Payload, Signature 세 부분을 Base64 Url-Safe 방식으로 인코딩하고 dot을 구분자로 결합한다.

- Header - JWT를 검증하는데 필요한 정보를 담고 있다.(토큰 타입, 사용된 알고리즘)
- 알고리즘은 HMAC, RSA 방식을 지원한다.
- 아래 그림에서 HS512는 HMAC usin SHA-512를 의미한다.
- HMAC 알고리즘에서 비밀키는 최소한 알고리즘의 서명 길이만큼의 비트를 가지고 있어야 한다.(HS512 - 64byte)
- Payload
- JWT를 통해 전달하고자 하는 데이터 - Claim-Set 이라고도 한다.
- Caim 자체는 쉽게 말해 key-value 데이터 쌍을 의미한다.
- JWT 자체는 암호화되는 것이 아니기 때문에 민감 정보를 노출해서는 안된다.
- Reserved Claims, Public Claims, Custom Claims 로 구분된다.
- Reserved Claims - 미리 등록된 Claims 필수적으로 사용할 필요는 없지만 사용을 권고한다.
- iss - 토큰을 발급한 발급자(Issuer)
- exp - 만료시간이 지난 토큰은 사용 불가
- nbf - Not Before의 의미로 해당 시간 이전에는 토큰 사용 불가
- iat - 토큰이 발급된 시각
- jti - JWT ID로 토큰에 대한 식별자
- Public Claims - 사용자 마음대로 쓸 수 있으나 충돌 방지를 위해 미리 정의된 이름으로 사용을 권고한다.
- Custom Claims - 사용자 정의 Claims(Reserved, Public에 정의된 이름과 중복되지 않도록 해야한다.)
- Signature
- 토큰이 생성 주체만 알고 있는 비밀키를 이용해 헤더에 정의된 알고리즘으로 서명된 값
- 토큰이 위변조 되지 않았음을 증명한다.
JWT의 장단점
- 장점
- 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 따로 스토리지가 필요 없다.
- 수평확장이 매우 쉽다 - Session Cluster 필요없음
- 따라서, Active User가 많은 서비스에서 JWT 사용이 유리하다.
- 세션을 사용할 경우 Active User 수 만큼 세션을 저장해야 하기 때문에 스토리지 관리가 어렵기 때문이다.
- 단점
- 토큰 크기를 가능한 작게 유지해야 한다.
- 토큰 자체가 항상 HTTP 요청에 포함되어야 하기 때문에 토큰이 커질수록 불리하다.
- 유효기간이 남아있는 정상적인 토큰에 대해 강제적으로 만료 처리가 어렵다.
- 세션을 동시에 사용할 경우 세션제어, 세션 만료처리 등 보안상 이점이 있다.