포스트

세션과 토큰, 그리고 JWT


이전에 공부했던 JWT의 개념과 구조, 인증 서버까지 복습하기 위해 다시 작성한다.

이전 블로그와 내용이 겹치지 않을까 싶지만, 해당 내용보다는 조금 더 상세하게 서술할 것이다.

JWT의 개념을 서술하기 앞서 세션 인증 방식과 토큰 인증 방식에 대해 먼저 이해하고, 토큰 방식인 JWT의 개념을 알아볼 것이다.



인증과 인가 처리는 보안에서 아주 중요한 요소이다.

사용자의 자격 증명을 서버에서 제대로 확인, 처리하지 않게 되면 보안이 아주 취약하다고 볼 수 있으며, 고객의 ID와 PW를 누구나가 손쉽게 탈취하여 큰 타격이 있을 수 있다.

특히나 ‘돈’이 관련된 파트라면 정말 생각도 하기 싫을 정도이다.

언제나 나와 팀원이 만든 애플리케이션은 누군가가 지켜보고 있으며 반드시 공격자가 있다는 가정을 해야한다.

그렇다면 이러한 공격자로부터 우리의 애플리케이션을 안전하게 지키기 위해서는 무엇이 필요할까?

여러 가지가 있겠지만, 기본적인 것은 바로 ‘자격 증명’이다.


누구나가 다 동일한 자격을 가질 순 없다.

예를 들어, 회원 가입을 하지 않은 유저가 우리 애플리케이션에 접근해 모든 자료를 탈취한다면?

혹은 회원 가입한 유저의 정보를 탈취해 금액적인 피해를 입힌다면?

이를 피하기 위해 서버에서는 현재 요청을 보내는 클라이언트에게 각각 ‘자격’을 부여하고, 해당 자격에 따른 요청을 할 수 있게끔 설정해야한다.

이렇게, 보안을 위해 서버에서 설정할 수 있는 방법은 크게 두 가지가 있다.

하나는 세션 기반 자격 증명 방식이고, 또 하나는 토큰 기반 자격 증명 방식이다.



1.세션 기반 자격 증명 방식

세션 기반 자격 증명 방식은 사용자가 웹 사이트에 로그인을 하게 되면 서버에서 세션 ID를 생성하고 이를 사용자의 블라우저에 쿠키로 저장하는 방식이다.

사용자가 서버에 요청을 보낼 때마다 이 쿠키를 함께 보내게 되고, 서버에서는 이 세션 ID를 통해 ‘세션 저장소’의 내용과 비교하여 사용자 정보를 확인하게 된다.

이 방식은 상태를 유지하기 때문에 상태 기반 인증 방식(Stateful Authentication)이라고도 불린다.

동작 방식을 그림으로 보면 아래와 같다.


이 그림에서 처럼 클라이언트가 로그인 후 요청을 보내면 서버는 세션 ID를 담은 쿠키를 응답과 함께 보내준다.


그 다음, 로그인 상태 즉, 쿠키에 세션 ID가 담겨 있는 상태로 클라이언트가 서버에 요청을 보내게 되면 세션 ID가 함께 보내진다.

이 때, 서버는 해당 세션 ID를 바탕으로 세션 저장소에서 조회하여 사용자 정보를 찾게 되고 정보가 있다면 응답을 한다.


이러한 세션 기반 증명 방식의 장단점은 다음과 같다.

  • 장점
    1. 서버가 사용자의 상태를 계속 추적하고 관리하기 때문에 보안성이 높다.
    2. 세션 데이터를 서버에서 관리하므로 클라이언트를 신뢰할 필요가 없다.
  • 단점
    1. 서버에서 세션을 관리해야하기 때문에 서버의 부하가 늘어날 수 있다.
    2. 사용자가 많아지면 세션 정보를 저장하기 위한 서버의 메모리 사용량이 증가한다.
    3. 서버 기반의 세션 관리는 분산 시스템 환경에서 관리가 어려울 수 있다.


이런 세션 기반 자격 증명 방식은 SSR 방식에서 유리하다.

이 SSR 방식은 Server Side Rendering, 쉽게 말해 서버에서 웹 페이지를 렌더링 하는 방식을 의미한다.

즉, SSR은 사용자가 웹 페이지에 접속하게 되면 서버에서 HTML, CSS, Java Script 등을 생성하여 사용자의 브라우저에 전송한다.

이러한 방식이 유리한 이유는 각 요청 마다 서버로부터 페이지를 다시 불러오기 때문에, 이 때마다 사용자를 인증할 수 있는 세션 기반의 인증 방식이 잘 맞기 때문이다.



2. 토큰 기반 자격 증명 방식

세션 기반과 달리 토큰 기반 자격 증명 방식은 사용자의 상태를 서버가 아닌 클라이언트 측에서 관리하는 방식이다.

사용자가 로그인을 하게 되면 서버에서는 사용자의 정보를 암호화한 토큰을 생성하여 클라이언트에게 전달한다.

클라이언트는 이 토큰을 저장해두었다가 서버에 요청을 보낼 때마다 이 토큰을 함께 보내 사용자를 인증한다.

그림으로 보면 아래와 같다.


우선 사용자가 로그인을 하게 되면 해당 로그인 정보를 바탕으로 서버에서 확인한 다음 토큰을 생성한다.

해당 토큰을 클라이언트에 보낸다.


위 그림과 같이 로그인된 사용자가 서버로 요청을 보내면 클라이언트가 토큰을 함께 서버로 보내게되고, 이 토큰을 기반으로 서버 내에서 인증 처리를 한다.

인증 처리가 완료되고 인가된 사용자라면 응답을 리턴한다.


이러한 토큰 기반 증명 방식의 장단점은 다음과 같다.

  • 장점
    1. 서버에서 사용자의 상태를 유지할 필요가 없으므로 서버의 부하를 줄일 수 있다.
    2. 토큰은 클라이언트 측에서 저장하고 관리하므로 서버의 확장성이 좋다.
    3. 토큰은 다양한 도메인 간에도 사용할 수 있으므로 Single Sign On(SSO) 구현에 유리하다.
  • 단점
    1. 토큰은 일정 기간 동안 유효하므로 토큰이 탈취당하면 그 기간 동안 보안 문제가 발생할 수 있다.
    2. 토큰의 크기가 크므로 네트워크 부하가 증가할 수 있다.
    3. 토큰 기반 방식은 CSRF(Cross-Site Request Forgery) 공격에 취약할 수 있다.

이러한 토큰 기반 자격 증명 방식은 CSR(Client Side Rendering) 방식의 애플리케이션에서 많이 사용되는데, 이는 토큰 기반 방식이 클라이언트 측에서 사용자의 상태를 관리하는 방식이기 때문에 클라이언트 측에서 대부분의 로직이 처리되는 CSR 방식과 어울리기 때문이다.



여기서 JWT(Json Web Token)는 말 그대로 토큰을 기반으로 자격 증명을 하기 때문에 토큰 기반 자격 증명 방식을 구현하는데 많이 사용된다.

특히 나는 CSR 방식의 웹 애플리케이션을 주로 구현하기 때문에 CRS 방식과 어울리는 JWT를 사용한다.



3. Json Web Token

JWT는 데이터를 안전하고 간결하게 전송하기 위해 고안된 인터넷 표준 증명 방식이다.

주로 토큰 기반 자격 증명 방식에서 가장 범용적으로 사용되는 기술이다.

Json 포맷의 토큰 정보를 인코딩한 다음, 인코딩된 토큰 정보를 임의로 지정된 Secret Key로 서명한 메시지를 Web Token 으로 인증 과정에 사용한다.

이 JWT는 두 가지 종류의 토큰을 사용자의 자격 증명에 이용한다.

하나는 액세스 토큰(Access Token)이고 하나는 리프레쉬 토큰(Refresh Token)이다.

여기서 액세스 토큰은 주로 보호된 정보들(사용자의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한 부여에 사용되며, 클라이언트가 실제로 권한을 얻는 데에 사용되는 토큰이다.

리프레쉬 토큰의 경우 주로 액세스 토큰이 기간이 만료되면 상대적으로 라이프 사이클이 긴 리프레쉬 토큰을 기반으로 다시 액세스 토큰을 발급 받기 위해 사용된다.

하지만 공격자 역시 이러한 토큰을 노리고 있기 때문에 리프레쉬 토큰의 경우 발급을 하지만 사용되지 않는 웹 애플리케이션도 존재한다.


탈취 당한다면?

이러한 토큰이, 특히 액세스 토큰이 탈취 당한다면 보안이 뚫린 것과 같다.

즉, 이 액세스 토큰을 바탕으로 공격자는 모든 정보를 빼낼 수 있다.

그렇기 때문에 보통 액세스 토큰의 생명 주기를 굉장히 짧게 하거나, 블랙리스트로 등록해 탈취할 수 없게 만드는 것이 서버 개발자의 임무이다.

또한, 앞서 말했듯이 리프레쉬 토큰으로 액세스 토큰을 재발급 한다면 사용자는 편리하겠지만, 공격자 역시 웃고 있을 것이다.

그렇기 때문에 리프레쉬 토큰을 발급하지 않거나 사용하지 않는 웹 애플리케이션이 많다.



기본적인 세션, 토큰 기반의 인증 처리 방식을 알아보았고, 특히 토큰 기반의 JWT 인증 처리 개념에 대해 살펴보았다.

다음은 JWT의 기본 구조에 대해 포스트 할 것이다.





이전 네이버 블로그 당시 있던 내용들에 그림과 설명을 조금 더 추가했다.

사실 오늘 면접을 보고 왔는데, JWT 내용을 좀 더 자세히 알고 있으면 좋을 것이라는 조언을 들어 이 내용을 복습했다.

JWT 관련 내용을 다시 한 번 다 정리하고 나면 기업들이 많이 쓴다는 쿠버네티스를 공부할 것이다.

나는 도커가 더 우세할 줄 알았는데, 면접관님께서 쿠버네티스를 추천해주셨다.

여튼 이번 면접은 아쉽게도 알고 있는 지식을 말로 표현하기 어려웠지만, 이렇게 복습과 공부를 하는 만큼 다음은 다를 것이다.

이 블로그는 저작권자의 CC BY 4.0 라이센스를 따릅니다.