JWT 인증 방식에서 보안을 고려한 Access Token, Refresh Token 관리 방법

eggggg·2025년 8월 29일
0
post-thumbnail

목차

1. Access Token
2. Refresh Token
3. 토큰 재발급 과정
4. 기기별 Refresh Token 관리 방법

웹 및 모바일 애플리케이션에서 사용자를 인증하고 API에 접근 권한을 부여하는 데에는 Access TokenRefresh Token이라는 두 가지 주요 토큰이 사용된다. 이 둘은 각기 다른 목적으로 사용되지만, 보안과 사용자 편의성을 동시에 확보하기 위해 함께 작동하는 개념이다.


1. Access Token

사용자가 아이디와 비밀번호로 로그인하면, 서버는 이 둘을 모두 발급한다. Access Token은 실제 API에 접근할 때 사용되는 열쇠이며, 그 수명은 매우 짧다(보통 몇 분에서 1시간). 이렇게 수명이 짧은 이유는 토큰이 탈취되더라도 공격자가 시스템을 악용할 수 있는 시간을 최소화하기 위해서이다. 클라이언트는 이 토큰을 받아서 메모리와 같은 안전한 곳에 보관하며, 보호된 API를 호출할 때마다 요청 헤더에 이 토큰을 담아 보낸다.

  • 일반적인 만료 설정 시간 : 5분 ~ 30분 사이. 민감한 데이터(예: 금융정보)를 다루는 서비스라면 5분 이내로 더 짧게 설정
  • 관리 방법
    • Access Token서버측에 별도로 저장할 필요없이 토큰 자체에 만료시간정보(exp 클레임)를 포함한다. 클라이언트는 요청시 이 토큰을 보내고, 서버는 토큰을 검증할 때 만료시간을 확인한다.

2. Refresh Token

반면, Refresh Token은 새로운 Access Token을 발급받기 위한 재발급용 신분증 역할을 한다. Access Token이 만료되어 더 이상 유효하지 않을 때, 사용자가 다시 로그인하는 번거로움 없이 새로운 Access Token을 얻기 위해 사용된다. Refresh TokenAccess Token보다 수명이 훨씬 길며(보통 며칠에서 몇 달), 보안을 위해 HTTP Only 쿠키와 같은 더욱 안전한 저장소에 보관된다.

  • 일반적인 만료 설정 시간 : 1일 ~ 몇 주, 또는 몇 달
  • 관리 방법
    • 데이터베이스 저장 : Refresh Token은 데이터베이스에 저장하여 관리한다. 이를 통해 토큰이 만료되지 않았더라도 사용자가 로그아웃하거나 의심스로운 활동이 감지될 때 서버에서 강제로 만료(무효화)시킬 수 있다.
    • 회전(Rotation) 전략 : Refresh Token을 한번만 사용 가능하도록 설정하고, 새로운 Access Token을 발급할 때마다 새로운 Refresh Token도 함께 발급하여 이전 토큰을 무효화한다. 이렇게 하면 탈취된 토큰의 유효기간을 한 번으로 제한할 수 있다.
    • 사용자 활동 기반 만료 : 사용자가 일정 기간(예: 30일) 동안 로그인하지 않으면 Refresh Token을 만료시키는 정책을 적용할 수 있다.

3. 토큰 재발급 과정

  1. 초기 로그인 : 사용자가 아이디와 비밀번호로 로그인하면, 서버는 Access TokenRefresh Token을 모두 발급한다.
  2. API 요청 : 클라이언트는 Access Token을 사용하여 API를 호출한다.
  3. Access Token 만료 : 시간이 지나 Access Token이 만료되면 API 호출이 실패한다.
  4. 토큰 재발급 요청 : 클라이언트는 가지고 있던 Refresh Token을 서버로 보낸다.
  5. 새 토큰 발급 : 서버는 Refresh Token을 확인하고, 유효하다면 새로운 Access Token을 발급하여 클라이언트에게 전달한다. 이 과정에서 Refresh Token 자체도 새로 발급할 수 있다.
  6. 계속해서 API 사용 : 클라이언트는 새로 받은 접근 토큰으로 다시 API를 사용한다.
  7. Refresh Token의 만료 : Refresh Token이 만료되면 사용자는 다시 로그인을 통해 Access TokenRefresh Token을 새로 발급받는다. 또는 Refresh Token재발급 요청을 보냄으로써 Refresh Token을 재발급받을 수 있다.

4. 기기별 Refresh Token 관리 방법

왜 Refresh Token 에 기기 정보를 포함시키지 않고 따로 저장하는가?

토큰 기반 인증 시스템에서 Refresh Token은 사용자 세션을 안전하게 유지하는 중요한 열쇠이다. 하지만 많은 개발자들이 Refresh Token 자체에 기기 정보(예: IP 주소, 기기 유형)를 포함시키지 않고, 별도로 데이터베이스에 저장하는 방식을 채택한다. 이는 단순한 구현 방식을 넘어, 보안과 유연성을 동시에 확보하기 위한 가장 효과적인 전략이다.

토큰에 기기 정보를 포함하지 않는 이유: '무상태성'과 '유연성'의 충돌

JWT의 가장 큰 장점은 무상태성(Stateless) 이다. 토큰은 서명만으로 유효성을 검증할 수 있어, 매 요청마다 서버가 데이터베이스를 조회할 필요가 없다. 하지만 토큰 내부에 기기 정보를 넣는 순간, 이 장점은 사라진다.

  • 세션 유연성 저해: 사용자의 IP 주소는 끊임없이 변할 수 있다 (Wi-Fi에서 모바일 네트워크로 전환, 동적 IP 주소 할당 등). 만약 토큰에 IP 주소를 포함하면, IP가 변경될 때마다 토큰이 무효화되어 사용자는 다시 로그인해야 한다. 이는 사용자 경험을 심각하게 해친다.

  • 토큰의 불변성: JWT는 서명된 이후에는 페이로드(Payload)를 변경할 수 없다. 만약 기기 정보가 변경되거나, 특정 기기의 세션만 종료하고 싶을 때, 토큰 자체를 새로 발급해야 하는 비효율적인 상황이 발생한다.

  • 보안: 토큰에 기기 정보 외에 다른 민감한 데이터까지 포함되면, 토큰이 탈취되었을 때 더 많은 정보가 노출될 위험이 있다.

이러한 이유로, 토큰은 최소한의 필수 정보(사용자 ID, 권한)만 담아 가볍고 무상태성을 유지해야 한다.

기기별 고유 정보를 헤더에서 받아 따로 저장하는 이유

그렇다면 기기 구분은 어떻게 해야 할까? 정답은 바로 데이터베이스에 Refresh Token과 기기 정보를 함께 저장하는 것이다. 이 방식은 토큰의 무상태성을 유지하면서도 강력한 세션 관리를 가능하게 한다.

  • 로그아웃 기능의 정교함: 사용자가 로그아웃을 요청했을 때, 해당 기기에서 발급된 Refresh Token만 데이터베이스에서 삭제하여 다른 기기에는 영향을 주지 않고 로그아웃할 수 있다. 반면, "모든 기기에서 로그아웃" 기능은 해당 사용자의 모든 Refresh Token을 한 번에 삭제함으로써 구현할 수 있습니다.

  • 보안 강화: 토큰을 발급할 때 저장한 IP 주소, User-Agent 정보와 실제 요청의 정보를 비교하여 토큰 탈취 여부를 감지할 수 있다. 예를 들어, 토큰 발급 시 IP와 갱신 요청 시 IP가 다르면 의심스러운 활동으로 간주하고 토큰을 무효화할 수 있다.

  • 사용자 편의 기능: 데이터베이스에 저장된 기기 정보를 통해 "내 계정 활동" 페이지를 구현할 수 있다. 사용자는 로그인된 기기 목록을 확인하고, 불필요한 세션을 직접 종료할 수 있다.

어떤 정보들을 저장해야 하는가?

토큰 생성 시 기기 식별을 위해 주로 HTTP 요청 헤더에서 다음과 같은 정보들을 추출하여 Refresh Token과 함께 데이터베이스에 저장한다.

  • User-Agent: 사용자의 운영체제, 브라우저 종류, 기기 유형을 알 수 있는 가장 기본적인 정보이다.

  • IP 주소: 사용자의 네트워크 위치를 파악하는 데 유용하다.

  • 기타 식별자: 모바일 앱의 경우, 기기 고유의 UUID를 헤더에 포함시켜 더 정확하게 기기를 식별할 수 있다.

0개의 댓글