Part 1. JWT’s Basic Information
JSON Web Token
JSON 포맷을 이용한 Web Token
Claim based Token
두 개체에서 JSON 객체를 이용해 Self-contained 방식으로 정보를 안전하게 전달
회원 인증, 정보 전달에 주로 사용
Claim based?
Claim
: 사용자에 대한 프로퍼티 / 속성
토큰 자체가 정보
Self-contained
: 자체 포함, 즉 토큰 자체가 정보
key / value
Part 2. Web Token
웹 토큰의 필요성
CSRF, 기존 시스템의 보안 문제
CORS, 도메인 확장 시 api로서의 문제
Web, Mobile 등 다양한 클라이언트
Session의 한계
Scale out의 한계
REST API : REST API는 Stateless를 지향
현재 우리는?
그런데 아직도 Cookie??
쿠키 기반 로그인의 문제점은 너무 많다
Server side Session 기반으로 넘어갈 것인가?
쿠키 기반 인증은 두말할 것 없이 변경해야 하고, 보편적 Session으로 갈 것인가?
Part 3. Type of Authorization
Cookie - Client Side Storage
문제점 투성이
Session - Sever Side Authorization
Cookie와 차이점은 Cookie는 정보를 클라이언트에 저장하고 Session은 정보를 서버에 저장한다.
Session Problem 1 - 서버 확장 시 세션 정보의 동기화 문제
서버가 스케일 아웃돼서 여러 개가 생기면 각 서버마다 세션 정보가 저장된다.
로그인 시(서버 1), 새로고침(서버 2)으로 접근하면 서버는 인증이 안됐다고 판단한다.
Session Problem 2 - 서버 / 세션 저장소의 부하
세션을 각 서버에 저장하지 않고 세션 전용 서버, DB에 저장해도 문제가 생긴다.
모든 요청 시 해당 서버에 조회해야 한다. DB 부하를 야기할 수 있다.
Session Problem 3 - 웹 / 앱 간의 상이한 쿠키-세션 처리 로직
기존의 Client는 웹 브라우저가 유일했다. 그러나 이제는 모바일로 접근하는 경우도 처리해야 한다.
웹 / 앱의 쿠키 처리 방법이 다르고 또 다른 Client 가 생겨나면 쿠키-세션에 맞게 처리해야 한다.
Token - Self-contained & Stateless
앞의 문제를 해결하는 최선의 방법은 토큰이다.
토큰은 서버의 상태를 저장하지 않는다. 토큰 자체로 정보를 가지고 있기 때문에 별도의 인증서버가 필요 없다. 따라서 요청을 받을 서버 자체에서 인증 프로세스를 수행할 수 있다.
또한, JSON 포맷으로 통신하기 때문에 어떤 Client 에서든 Data 통신에 JSON을 이용하면 토큰을 이용할 수 있다.
Part 4. JWT’s Architecture
JWT의 기본 구조
Header . Payload . Signature
Header
JWT 웹 토큰의 헤더 정보
typ
: 토큰의 타입, JWT만 존재
alg
: 해싱 알고리즘. (HMAC SHA256 or RSA). 헤더를 암호화하는 게 아니다. 토큰 검증 시 사용.
{
"alg" : "HS256",
"typ" : "JWT"
}
위의 내용을 base64로 인코딩한다. => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
base 64는
Payload
실제 토큰으로 사용하려는 데이터가 담기는 부분. 각 데이터를 Claim이라고 하며 다음과 같이 3가지 종류가 있다.
Reserved claims
: 이미 예약된 Claim. 필수는 아니지만 사용하길 권장. key는 모두 3자리 String이다.
iss (String) : issuer, 토큰 발행자 정보
exp (Number) : expiration time, 만료일
sub (String) : subject, 제목
aud (String) : audience,
Public claims
: 사용자 정의 Claim.
Public이라는 이름처럼 공개용 정보
충돌 방지를 위해 URI 포맷을 이용해 저장한다.
Private claims
: 사용자 정의 Claim
Public claims과 다르게 사용자가 임의로 정한 정보
아래와 같이 일반 정보를 저장한다.
-
{ "name" : "hak", "age" : 26, }
Signature
Header와 Payload의 데이터 무결성과 변조 방지를 위한 서명
Header + Payload를 합친 후, Secret 키와 함께 Header의 해싱 알고리즘으로 인코딩
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
JWT 구조
JWT는 [Header Payload Signature] 각각 JSON 형태의 데이터를 base 64
인코딩 후 합친다.
아래와 같은 순서로. 을 이용해 합친다.
최종적으로 만들어진 토큰은 HTTP 통신 간 이용되며, Authorization이라는
key
의 value
로서 사용된다.
JWT 인증 과정
Part 5. Is JWT a Silver bullet?
그렇다면 모든 서비스들은 기존의 쿠키-세션 기반에서 웹 토큰 기반의 인증으로 변경해야 할까?
JWT의 단점 & 도입 시 고려사항
Self-contained
: 토큰 자체에 정보가 있다는 사실은 양날의 검이 될 수 있다.
토큰 길이
: 토큰 자체 payload에 Claim set을 저장하기 때문에 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.
payload 암호화
: payload 자체는 암호화되지 않고 base64로 인코딩한 데이터다.
중간에 payload를 탈취하면 디코딩을 통해 테이터를 볼 수 있다.
JWE를 통해 암호화하거나, payload에 중요 데이터를 넣지 않아야 한다.
Stateless
: 무상태성이 때론 불편할 수 있다. 토큰은 한번 만들면 서버에서 제어가 불가능하다.
토큰을 임의로 삭제할 수 있는 방법이 없기 때문에 토큰 만료시간을 꼭 넣어주는 게 좋다.
tore Token
: 토큰은 클라이언트 side에서 관리해야 하기 때문에 토큰을 저장해야 한다.
Conclusion
HTTP, REST API의 공통적인 특징은 Stateless
(무상태)를 지향한다는 것이다.Stateful
, 즉 상태를 저장하는 서버는 많은 Side-effect를 발생시킬 수 있다.
또한, 서론에 말했듯이 현재의 IT 인프라 구조는 유연한 확장 가능성이 있어야 하는데 기존의 쿠키-세션 기반의 인증을 사용하면 확장 가능한 인프라를 구성하기 힘들다.
기존의 로그인 / 인증을 모두 Web Token 기반으로 변경할 수는 없지만, 앞으로 만들게 될 서비스 특히 RESTful 한 API의 인증에는 JWT를 사용해보는 것이 좋을 것이라 생각한다.
( JWT 인증 예제 - https://github.com/SangHakLee/nodejs-jwt-example-ryan).
Reference
1. https://sanghaklee.tistory.com/47 [이상학의 개발 블로그]
'Development > Terms' 카테고리의 다른 글
[Terms] CBOR (0) | 2019.03.12 |
---|---|
[Terms] CDN (0) | 2016.03.23 |