본문 바로가기

개발

JWT(Json Web Token) 를 알아보자

JWT란?

JWT는 JSON 객체를 사용해서 유저를 인증하고 식별하기 위한 토큰기반 인증이다.

토큰 자체에 정보를 포함하고 있으며 세션처럼 서버에 저장할 필요가 없고

요청시 HTTP 헤더에 토큰을 첨부하면 데이터 요청과 응답을 할 수 있다.

 

JWT는 JSON을 Base64 URL-safe Encode를 통해 인코딩해서 직렬화하며 위변조 방지를 위한 전자서명이 포함된다.

개인키(시크릿키)를 통해 검증을 하며 검증이 완료되면 요청한 응답을 돌려준다.

 

JWT로 로그인을 구현한다면 다음과 같은 순서로 진행된다.

1. 클라이언트가 아이디와 패스워드를 입력 후 인증

2. 서버에서 아이디와 패스워드가 정확하다면 서명된(Signed) JWT을 생성 후 클라이언트에 전달

3. 로그인 성공 후 클라이언트가 서버를 호출할 때 HTTP Header에 서버에서 넘어온 JWT을 첨부

4. 서버에서 JWT를 검증 후 데이터 응답

 

JWT구조

JWT의 구조는 크게 3개로 구성된다. 이 요소는 .으로 구분된다.

1. Header : 토큰타입과 해시 알고리즘 종류를 포함

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

2. Payload : 서버에서 설정한 정보 및 토큰 관련 정보 포함

3. Signature : Header, Payload를 Base64 URL-safe Encode로 인코딩 한 후 Header에 명시된 해시함수를 적용하고 개인키로 서명한 전자서명 포함

 

JWT를 왜 사용하는가?

HTTP의 비상태성(Stateless)으로 인해 서버는 고객이 이전에 인증(로그인)을 거친 사용자인지 모른다.

이러한 문제점을 해결하기 위해 세션 혹은 토큰을 이용하고 있다. 

 

세션의 경우 사용자가 로그인을 할 경우 사용자 인증정보를  서버의 세션 저장소에 저장하고 Session ID를 발급한다.

클라이언트는 Session ID를 쿠키에 저장하고 다음 요청시 쿠키 헤더에 넣어서 서버로 요청하고 서버에서 이 세션 아이디가 서버에 저장되어 있는지 확인 후 있다면 로그인한 사용자라고 판단한다. 

세션은 서버에 저장되어 있기때문에 안전한 방법이고 Session ID를 탈취당한다고 해도 서버에서 Session ID를 무효화하면 된다.

또한 Session ID만 실어서 보내면 되기때문에 크기가 작아 적은 네트워크 트래픽을 소요한다. 

 

반면에 JWT는 서버에 저장되어 있지 않다. 클라이언트의 local storage나 cookie에 저장된다. 

그러므로 보안에 상대적으로 취약하고 탈취를 당하더라도 토큰 만료시간이 끝나지 않으면 무효화하는데 별도의 로직을 개발해야 한다.

이것이 토큰 만료시간을 짧게 설정하는 이유이기도 하다. 그럼 또 refresh token을 적용해야하고..아이고 ... 

또한 토큰의 크기는 세션 아이디에 비해 클 수밖에 없으므로 네트워크 트래픽도 많이 소요된다.

 

그렇다면 왜 JWT를 사용하는 것일까?

다수의 서버를 운용하는 환경이 많아졌고 서버를 확장할 때 보통 수평확장(서버의 수를 늘리는 방법)을 한다. (수직 확장 : 서버의 사양을 향상시키는 방법 그러나 수평확장에 비해 비용이 비싸다.)

 

세션은 서버의 메모리 영역에 저장되는 값이다. 그러므로 서버가 여러대일 경우 세션 불일치 현상이 일어난다. 

즉 A와 B서버가 있을 때, A서버 메모리에 저장된 세션 아이디는 B서버와 공유되지 않기때문에

사용자의 로그인을 A서버에서 처리했다면 이후 사용자가 B서버에 요청을 보냈을 때는 세션 아이디가 B서버에는 없기때문에

비로그인 상태라고 판단되어 로그인을 유도하는 페이지로 이동하는 등의 문제가 발생할 것이다.

이런 문제를 해결하기 위해서는 세션 클러스터링이나 세션 스토리지를 외부로 분리해서 다수의 서버가 하나의 세션 스토리지를 보게끔하는등의 방법이 있지만 이렇게 할 경우 매 요청마다 세션을 확인하기 위해 외부에 저장된 값을 읽어들이는 등 좋지않는 성능을 유발할 수 있다.

 

그러나 JWT는 클라이언트에 저장되고 서버에서는 전자서명을 확인하는 방법이므로 이런 세션 불일치 문제를 해결 할 수 있다.

이러한 확장성때문에 JWT를 사용한다. 만약 다수의 서버를 사용할 일이 없다고하면 세션을 사용하여 인가를 하는것도 좋은 방법이라고 생각한다. 그러나 서버일 모르는것이기 때문에 추후 확장성을 고려한다면 JWT를 사용하는것을 권장한다.

 

반응형