JWT

[JWT] 로그인 세션 관리하기 1 (JWT에 관하여)

마뇨기 2024. 2. 1. 01:45

 

 

 

오늘이 아시안컵 16강이 있던 날인데,

축구를 보니 볼 차고 싶은 생각이 너무 들던 하루,,,

(사진은 축구하고 있는 나)

 


 

 

오늘은 프론트엔드를 개발하면서 로그인 세션을 어떻게 관리하였는지 작성해보겠다.

서버에서는 사용자가 로그인 되어 있는지 알 필요가 있다. 이를 위해 JWT 라는 것을 사용한다.

 

 

JWT 란 무엇이고 왜 필요할까?

 

 

1. JWT란?

JWT (JSON Web Token)는 Json 형식을 이용하여 사용자의 속성을 저장하는 Token이다.

즉, 정보를 비밀리에 전달하거나 사용자 인증 시 사용된다.

 

ex)

  • 앱을 실행했을 때 사용자가 가진 JWT를 비교하여 자동로그인을 기능을 제공
  • 상품 구매, 예약 신청 등을 시도할 때 사용자 인증

 

2. JWT가 필요한 이유

 

1) 무상태성 (Statelessness)

JWT가 필요한 첫 번째 이유는 무상태성 (statelessness)이다.

우선 무상태성이 무엇인지 짚고 넘어갈 필요가 있다.

 

웹 서버가 사용자의 상태를 계속해서 기억하지 않는 것을 "무상태성"이라고 한다.

 

예를 들어, 웹사이트에 접속할 때마다 사용자가 로그인을 해야 하면 그 웹사이트는 무상태적이다. 반대로 사용자가 한 번 로그인하면 그 상태를 계속 기억하고 있는 웹사이트는 "유상태적"이라고 할 수 있다.

 

현대의 웹 애플리케이션은 확장성 (시스템, 네트워크, 프로세스 등이 부하가 증가할 때 그것을 효과적으로 처리할 수 있는 능력) 을 유지하기 위해 상태를 유지하지 않는다는 원칙을 따르는 경우가 많다.

JWT는 이런 무상태적 환경에서도 사용자의 인증 정보나 권한 등을 안전하게 전달하고 관리하는 방법을 제공한다.

  • JWT는 사용자 ID, 권한 등 필요한 정보를 포함하므로, 사용자가 요청을 할 때마다 데이터베이스에 접근하여 인증 정보를 확인할 필요가 없다.
  • 사용자가 로그인하면 JWT가 반환되고, 이후 요청에는 이 토큰을 사용하여 서버에서 빠르게 인증할 수 있다. 이로 인해 서버는 무상태성을 유지하면서 효율적으로 인증 처리를 할 수 있다.

 

2) 웹 모바일 모두 활용 가능

 

JWT는 HTTP 헤더에 쉽게 포함될 수 있으므로, 모바일 애플리케이션에서도 쉽게 사용할 수 있다.

 

3) 보안

어쩌면 JWT를 사용하는 가장 중요한 사항이다.

JWT는 *디지털 서명을 통해 *데이터의 무결성을 보장한다. 서명은 비밀키를 통해 생성되기 때문에, 서명을 검증하는 측이 해당 키를 알고 있지 않는 한 토큰을 위변조할 수 없다.

 

*디지털 서명 : 네트워크에서 송신자의 신원을 증명하는 방법

*데이터의 무결성 : 데이터의 정확성, 일관성, 유효성이 유지되는 것

 

4) 필요한 모든 데이터를 포함

무상태성 (Statelessness) 에서도 언급했지만, JWT는 필요한 모든 정보를 자체적으로 가지고 있다.

이러한 점 덕분에, 중앙의 인증 서버나 데이터베이스에 의존하지 않고도 사용자의 상태와 권한을 검증할 수 있다.

 

 

3. JWT 구조 (생김새)

JWT 구조

 

JWT는 보통은 “ey”로 시작하며, 3개의 부분으로 나누어져 있고 각 부분은 점(.)으로 구분되어 있다.

 

  • Header: 토큰 유형과 토큰을 검증하는데 필요한 서명 알고리즘으로 구성되어 있다.
  • Payload: 토큰에 저장할 데이터들로 구성되어 있다. 위의 예시는 id와 name, 그리고 권한을 확인하기 위한 auth로 구성했다.
  • Signature: 가장 중요한 부분으로 헤더와 정보를 합친 후 발급해준 서버가 지정한 secret key로 암호화 시켜 토큰을 변조하기 어렵게 만들어준다.

 

 

4. JWT는 어떻게 활용될까? (Access Token, Refresh Token)

 

JWT는 서버 측 *리소스에 접근할 때 클라이언트 본인을 인증할 수 있도록 액세스 토큰(Access Token)을 발급한다.

 

"리소스에 접근한다"는 말은 “웹사이트나 앱의 특정 기능이나 정보를 사용하려고 할 때”라고 볼 수 있다.

다시 말해, 특정 정보나 기능을 사용하려고 시도하는 것을 의미한다.

 

 하지만, JWT무상태성(Statelessness)의 방식이기 때문에 서버 측에서는 이 토큰을 갖고 있는 클라이언트가 정말 클라이언트 본인이 맞는지 확인할 수 없다는 문제점이 있다. 만약 Access Token을 다른 사람에게 탈취 당한다면 누가 본인인지 전혀 알 수가 없을 것이다.

 그래서 이에 대한 보안 대책으로 리프레쉬 토큰(Refresh Token)이라는 추가적인 토큰이 제공된다. 이 토큰은 사용자 인증이 아닌 새로운 Access Token을 생성하는 용도로만 활용된다.

구체적인 리프레쉬 토큰(Refresh Token)의 구체적인 내용은 좀 더 뒤에 다뤄보자.

 

 

1) Access Token과 Refresh Token의 발급과 사용

 

Access TokenRefresh Token을 간단하게 말하자면 다음과 같이 설명할 수 있다.

 

  • Access Token: 사용자의 인증 및 권한을 확인하기 위한 토큰으로, 짧은 유효 기간을 가진다.
  • Refresh Token: Access Token이 만료되었을 때 새로운 Access Token을 발급 받기 위한 토큰. 일반적으로 긴 유효 기간을 가진다.

 

 

그러면, Access TokenRefresh Token이 어떤 과정에서 얻을 수 있고, 사용될까?

 

  1. Token 발급 (로그인 과정)
    1. 사용자가 ID와 비밀번호를 통해 로그인을 시도한다.
    2. 서버(백엔드)에서는 로그인 정보를 검증하고, 성공적인 경우 Access Token과 Refresh Token을 생성한다.
    3. 생성된 두 토큰을 사용자에게 전달된다.
    4. 이 때, 프론트엔드가 설정한 방식에 따라 사용자는 두 가지의 토큰을 보관하게 된다.
  2. Token 사용 1 (리소스 접근)
    1. 사용자는 리소스에 접근할 때 Access Token을 헤더에 포함 시켜 서버에 전송한다.
    2. 서버는 Access Token의 유효성을 검증하고, 유효한 경우 해당 리소스에 대한 접근을 허용한다.
    3. 상품 구매, 예약 신청 등을 시도할 때 서버에 Access Token을 넘겨줌으로써 유효성 검증을 하고 원하는 리소스에 접근할 수 있다.
  3. Token 사용 2 (자동로그인)
    1. 첫 로그인 시 : 사용자는 Access Token을 발급 받고, 클라이언트(웹사이트 앱)는 받은 Token을 안전하게 저장합니다.
    2. 재접속 시 : 사용자가 애플리케이션을 다시 방문하거나 앱을 다시 실행할 때, 클라이언트는 저장했던 Access Token을 가져와 서버에 전송한다.
    3. 서버는 받은 Access Token의 유효성을 검증한다. 토큰이 유효하면 사용자는 자동로그인 상태가 되며, 로그인 과정 없이 서비스를 이용할 수 있다.

 

2) Token의 재발급

 앞선 내용에서 Access Token은 짧고, Refresh Token은 긴 유효 기간을 가진다고 하였다.

Access Token의 유효 기간이 짧은 이유는 Token을 탈취 당했을 때를 대비하기 위함이다. 공격자는 유출된 Token을 탈취하더라도 유효 기간이 지나면 사용할 수 없다. Token을 주기적으로 재발급 받도록 하여 Token이 유출되더라도 그 피해를 최소화한다는 방식인 것이다.

 

 하지만 그렇다면 정상적인 클라이언트도 짧은 주기마다 다시 로그인해서 Access Token을 발급받아야 한다는 단점이 있다. 그래서 여기서 유효 기간이 긴 Refresh Token을 사용하는데, 정상적인 사용자는 Access Token이 만료됐다면 서버측에 Refresh Token을 전송하여 다시 로그인할 필요 없이 Access Token을 발급받을 수 있다. 당연히 이 Refresh Token이 없는 공격자는 다시 토큰을 발급받을 수 없기 때문에 보안 측면에서 좀 더 안전하다고 할 수 있다.

 

 


 

 

여기까지는 JWT에 대해 알아보았다.

다음 글에서는 글 작성자의 프로젝트 (프론트엔드 개발 파트)에서 JWT를 어떻게 관리하고 있는지 정리될 예정이니 참고하면 좋을 것 같다.