Q> Session와 JWT(JSON Web Token) 인증방식에 대한 문의

저는 회사에서 기술적 보안을 담당자입니다. 개발자와 얘기하다 보니, JWT Token 방식은 기존의 Session 방식과 다르게 서버에 JWT를 저장하지 않는다고 하는데, 그렇다면 클라이언트를 어떻게 인증하는지 알고 싶습니다.

A>

JWT(JSON Web Token)는 Session방식과 다르게, JWT 자체로 필요한 인증 및 권한정보를 포함하는 상태로 설계되어 있기 때문에, 전통적인 Session기반의 인증방식과는 다르게 서버 측에서 JWT Token을 별도로 저장할 필요가 없다.
그러나 Token Whitelisting 또는 Blacklisting을 위해 JWT를 서버에 저장하는 경우도 있다.

<> JWT방식은 왜 등장하게 되었는가?

- 기존의 전통적인 Session방식은 stateful방식으로써 모든 클라이언트의 session정보를 서버(데이터베이스나 캐쉬)에 저장하고 있어야 한다. 따라서 서버의 부하가 높을수 밖에 없다.
- 특히, 수많은 Microservice들로 구성되는 Microservice Architecture 환경의 경우, Session방식은 서버의 부하가 훨씬 높아질수 밖에 없기 때문에 JWT기술은 더욱더 활발하게 사용되게 되었다.

<> JWT방식의 클라이언트 식별 및 인증과정을 요약하면...

클라이언트의 인증과정에 대하여 이해할 필요가 있다.

1. 토큰 생성

- 클라이언트가 로그인을 요청하면, 서버는 사용자의 정보(아이디, 비밀번호 등)을 검증한다.
- 인증이 성공하면 서버는 사용자 정보와 서버의 Private Key(또는 Secret Key)를 사용하여 JWT를 생성한다.
- 클라이언트 식별강화가 필요한 경우, 클라이언트의 IP, 브라우저의 User Agent, 클라이언트 디바이스의 공유한 특성을 JWT의 Payload에 포함시키거나 Challenge-Response Authentication 메커니즘을 이용하여 클라이언트 식별을 강화하는 방안이 사용되곤 한다.

2. 토큰 전송:

- 서버는 생성된 JWT를 일반적으로 HTTP Header 또는 Body에 포함시켜 클라이언트에게 전송한다.
== 3. 토큰 저장:
- 클라이언트는 받은 JWT를 쿠키나 로컬 스토리지, 세션 스토리지 등에 저장한다.

4. 토큰 사용:

- 클라이언트는 서버에 요청을 보낼 때마다 저장하고 있는 JWT를 HTTP Header에 포함시켜 전송한다.
- 주로 Authorization 헤더에 포함시켜 전송한다.

5. 토큰 검증:

- 서버는 클라이언트 요청을 받을때 마다 Header에 포함된 JWT를 검증하는데, 서버의 Private Key(또는 secret key)를 사용하여 Signature부분을 확인한다.
- JWT의 Signature가 유효하면 Payload부분을 디코딩하여 클라이언트의 정보를 확인하는데, 이를 통해 클라이언트를 식별하고 해당 권한에 따라 요청을 처리한다.
- 또한, JWT에 포함된 “exp”(유효기간)을 통해 토큰의 유효기간도 검증하도록 구현할 수 있다.

<> JWT는 서버에 저장하는 방식이 아니다.

- JWT는 자체적으로 사용자를 식별하는 정보를 갖고 있기 때문에 Session처럼 서버에 JWT를 저장할 필요가 없다.
- 즉, 클라이언트가 보내온 JWT를 자신의 Private Key로 검증함으로써 클라이언트를 식별한다.
- 따라서, 서버 입장에서는 통제권을 벗어난 JWT Token의 위변조 방지와 같은 보안을 강화하기 위한 방안이 필수적으로 필요하다.

<> JWT는 생성부터 검증까지는 이해했는데 폐기가 없는데요?

- 위의 인증과정에서와 같이, 서버는 자신이 생성한 JWT들을 서버에 저장하지 않기 때문에 임의로 폐기를 할수 없다.
- 그러나, 폐기와 유사한 기능으로써 Token Whitelisting 또는 Blacklisting을 구현하여 불필요해지거나 만료된 Token의 악용을 방지할 수 있다(API Gateway에서 이런 기능을 제공하는 제품도 있음)