
목차
API를 안전하게 운영하면서도 사용자 경험(UX)을 해치지 않는 것은 모든 개발자와 아키텍트의 숙제입니다. 특히 인증 토큰의 만료 시간을 어떻게 설정하느냐가 보안과 사용성의 균형을 잡는 핵심입니다. 토큰이 너무 길면 유출 시 위험이 커지고, 너무 짧으면 사용자가 계속 재인증해야 하는 불편함이 따릅니다.
이 글에서는 UX 저하 없이 위험 노출 시간을 최소화하는 액세스 토큰(Access Token)과 리프레시 토큰(Refresh Token)의 만료 및 회전 전략을 설계하는 방법을 구체적인 권장값과 함께 알아보겠습니다.
핵심 원칙: 왜 장기 토큰은 안티패턴인가?
전략을 세우기 전, 장기 토큰을 피해야 하는 이유부터 명확히 해야 합니다.
- 보안 취약점 증가: 토큰의 유효 시간이 길수록 탈취되었을 때 공격자가 시스템에 접근할 수 있는 시간(취약 창, Window of Vulnerability)이 늘어납니다.
- 성능 저하: 만료되지 않은 토큰이 데이터베이스에 계속 쌓이면 불필요한 부하를 유발하고 성능에 악영향을 줄 수 있습니다.
따라서 기본 전략은 "사용자 경험이 허용하는 한 가장 짧게 시작하고, 명확한 근거가 있을 때만 점진적으로 늘리는 것"입니다.
권장 기본값: 액세스 토큰 30분, 리프레시 토큰 24시간
어디서부터 시작해야 할지 막막하다면, 업계 표준을 따르는 것이 가장 좋습니다. Google Cloud Apigee에서는 액세스 토큰 30분, 리프레시 토큰 24시간을 합리적인 출발점으로 제시합니다.
서비스의 특성에 따라 이 값을 조정할 수 있습니다.
구분 | 액세스 토큰 | 리프레시 토큰 | 사전 갱신 (권장) | 오류 처리 요점 | 캐싱 전략 |
---|---|---|---|---|---|
금융 서비스 | 15–30분 | 24시간 | 잔여 20% 시점 | 재인증 유도, 세션 격리 | 서버 캐시, 재시도 제한 |
일반 SaaS | 30분 | 24시간 | 잔여 25% 시점 | 401 발생 시 투명한 안내 | 클라이언트 메모리 |
내부 API (M2M) | 5–15분 | 없음 또는 짧게 | 잔여 30% 시점 | 429 발생 시 백오프 적용 | 게이트웨이 토큰 캐시 |
끊김 없는 UX의 비밀: 사전 갱신 (Proactive Renewal)
사용자가 서비스를 이용하는 중에 갑자기 토큰이 만료되어 로그아웃되는 경험은 최악입니다. 이를 방지하기 위해 토큰이 완전히 만료되기 전에 미리 갱신하는 '사전 갱신' 로직이 필수입니다.
- 구현 방법: 액세스 토큰의 남은 수명이 20~30%인 구간에 진입하면 클라이언트가 자동으로 리프레시 토큰을 사용해 새 액세스 토큰을 발급받도록 합니다.
- 간단 계산식:
실제 세션 만료 시간 = 액세스 토큰 만료 시간 − 사전 갱신 임계 시간 + (재발급 지연 시간)
Apigee와 같은 API 게이트웨이는 토큰 만료 시간(ExpiresIn)을 런타임 변수로 관리하여 동적인 조정이 가능합니다. (단, 내부 캐시 정책으로 인해 최소 180초보다 짧은 만료 시간은 강제할 수 없는 경우도 있습니다.)
보안 강화: 토큰 회전, 블랙리스트, 그리고 즉시 철회
단순히 토큰을 갱신하는 것을 넘어, 탈취된 토큰을 무력화하는 고급 전략이 필요합니다.
1. 리프레시 토큰 회전 (Refresh Token Rotation)
리프레시 토큰 회전은 보안을 한 단계 끌어올리는 강력한 기능입니다. 토큰을 갱신할 때마다 기존 리프레시 토큰은 무효화하고 완전히 새로운 리프레시 토큰을 발급합니다.
- 장점: 만약 공격자가 이전에 탈취한 리프레시 토큰으로 재사용을 시도하면, 시스템이 이를 감지하고 해당 사용자 계정과 연결된 모든 토큰(토큰 패밀리)을 즉시 차단할 수 있습니다.
- 주의점: Auth0는 활성 리프레시 토큰이 과도하게 쌓이는 것을 막기 위해 만료 시간을 반드시 설정하고, 사용자/앱당 개수를 제한할 것을 권고합니다.
2. 블랙리스트(Denylist) 및 철회
사용자가 로그아웃하거나 관리자가 특정 세션을 강제로 종료할 때, 해당 토큰을 즉시 무효화해야 합니다.
- 동작 방식: API 게이트웨이의
InvalidateToken
과 같은 기능을 호출하여 토큰을 철회합니다. - 한계: Apigee의 경우, 캐시 정책으로 인해 철회 후에도 최대 180초간 토큰이 유효할 수 있습니다. 이 시간을 줄이기 위해 게이트웨이 단에 별도의 블랙리스트(Denylist)를 구현하거나, 서명 키를 교체(Key Rotation)하는 전략을 병행해야 합니다.
플랫폼별 맞춤 전략: 모바일, 웹, M2M
모든 환경에 동일한 정책을 적용할 수는 없습니다. 플랫폼 특성에 맞춰 전략을 최적화해야 합니다.
- 모바일/SPA (Single Page Application): 회전형 리프레시 토큰을 사용하고 메모리에 저장하여 서드파티 쿠키 제한(ITP) 환경에서도 원활한 세션 유지를 보장합니다. 네트워크 불안정에 대비한 지수 백오프 및 재시도 큐 로직이 필요합니다.
- 서버 (웹 백엔드): 리프레시 토큰은 짧은 만료 시간을 갖고, HSM/KMS 같은 보안 스토리지에 암호화하여 저장합니다. 세션 고정(Session Fixation) 공격을 막기 위해 디바이스 지문(fingerprint) 비교와 같은 추가 검증을 고려합니다.
- M2M (Machine-to-Machine): 5~15분의 짧은 액세스 토큰을 사용하되, API 게이트웨이 앞단에 토큰 캐싱 프록시를 두어 불필요한 토큰 발급 트래픽을 흡수하고 지연 시간을 줄입니다.
오류 처리: 401과 429에 현명하게 대처하기
- 401 Unauthorized (만료/철회): 토큰 검증 실패 시, 클라이언트는 즉시 토큰 재발급 플로우를 시작해야 합니다. 재발급마저 반복적으로 실패하면 사용자에게 강제 재인증을 요구합니다.
- 429 Too Many Requests (레이트 제한): 토큰 발급 요청이 단기간에 몰리면 발생합니다. 클라이언트는 지수 백오프(Exponential Backoff)와 랜덤 지터(Jitter)를 적용하여 재시도 간격을 점차 늘려야 서버 부하를 줄일 수 있습니다.
마무리하며: 안전한 토큰 전략을 위한 최종 체크리스트
효과적인 API 토큰 만료 전략을 위해 다음 항목들을 반드시 점검하세요.
- 만료 기본값 설정: 액세스 토큰 30분, 리프레시 토큰 24시간에서 시작했는가?
- 사전 갱신 로직: 토큰 만료 전(잔여 20~30%)에 갱신하는 로직이 구현되었는가?
- 보안 강화: 리프레시 토큰 회전, 블랙리스트, 즉시 폐기 경로가 마련되었는가?
- 오류 처리: 401/429 오류 코드에 대한 클라이언트의 재시도 및 백오프 규칙이 적용되었는가?
- 감사 로그: 토큰 발급, 갱신, 회전, 재사용 탐지 이벤트를 분석 가능한 로그로 남기고 있는가?
자주 묻는 질문 (FAQ)
Q. 토큰은 만료 시간의 몇 %가 남았을 때 재발급하는 게 가장 좋은가요?
A. 일반적으로 잔여 20~30% 구간이 안전합니다. M2M 통신처럼 트래픽 예측이 가능한 경우 30%로 조금 더 당겨서 발급 부하를 분산시킬 수 있습니다. Amazon Cognito는 토큰 수명의 75%를 사용한 후 갱신하는 것을 원칙으로 제시하기도 합니다.
Q. 모바일 환경의 잦은 네트워크 단절은 어떻게 대응해야 하나요?
A. 회전형 리프레시 토큰을 메모리에 캐시하고, 갱신 실패 시 오프라인 큐에 작업을 담아두었다가 연결이 복구되면 처리하는 방식을 사용합니다. 또한 ITP 같은 브라우저 정책에 의존하지 않는 네이티브 플로우를 설계하는 것이 중요합니다.
Q. 토큰 유출이 의심될 때 즉시 차단하는 순서는 어떻게 되나요?
A. (1) 해당 클라이언트의 리프레시 토큰 패밀리 전체를 철회합니다. (2) 유출된 액세스 토큰을 블랙리스트에 추가합니다. (3) 상황이 심각하다면 서명 키를 교체(Key Rotation)합니다. (4) 마지막으로 해당 사용자의 모든 세션을 종료하고 강제 재인증을 요구합니다.
함께 읽으면 좋은 글
※ 면책 조항: 본 글은 일반적인 보안 아키텍처 가이드이며, 실제 적용 시에는 각 조직의 규정, 위험 평가, 규제 요구사항에 따라 면밀한 검토와 테스트가 필요합니다.