🔑 JWT 토큰 ( Access Token, Refresh Token )
JWT (JSON Web Token)란?
- JWT는 JSON 형식의 데이터를 포함하고 있으며, 세 개의 부분으로 구성된 문자열이다: Header, Payload, Signature.
- 이 구조를 통해, 사용자와 서버 간의 통신에서 인증 정보를 안전하게 주고받을 수 있다.
JWT의 구성 요소
1. Header (헤더):
- 토큰 타입 (JWT)과 서명 알고리즘 (예: HMAC SHA256)을 정의.
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload (페이로드):
- 사용자 정보나 토큰의 클레임(claims)을 담고 있다. 이 정보는 인증 과정에서 사용된다.
- 예를 들어, 사용자 ID, 이메일, 권한 등과 같은 정보를 포함할 수 있습니다.
{
"sub": "user@example.com",
"name": "John Doe",
"role": "USER"
}
3. Signature (서명):
- 헤더와 페이로드를 비밀키를 사용해 서명한 값으로, 무결성을 보장한다.
- 서명을 통해 JWT가 변조되지 않았음을 확인할 수 있다.
- 서명은 HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 형식으로 만들어진다.
언제, 왜 사용하는가?
- 권한부여 -> 해당 토큰을 사용해 권한을 통한 허용된 경로를 체크하고 서비스에 엑세스가 가능하다.
- 정보교환 -> 당사자 간에 정보를 공개키, 개인키를 활용하는 방식을 사용하여 signature를 생성하여 발신자가 누구인지를 알 수 있도록하여 정보를 안전하게 전송할 수 있다. (무결성, 신뢰성 보장)
- 무상태성을 유지 -> 세션 기반 인증 방식은 사용자의 로그인 정보를 서버 측에서 관리하기 때문에, 서버에 부하가 발생할 수 있다. JWT를 사용하면 무상태성을 유지하면서 인증된 사용자의 자격을 증명할 수 있다. 즉, 사용자가 누구인지 기억할 필요 없이 토큰에 있는 정보에 접근 권한이 있는지만 체크하면 된다
무결성은 데이터가 허가되지 않은 방식으로 변경되지 않았음을 보장하는 속성
왜 무상태성을 유지해야 할까?
- **무상태성(stateless)**은 서버의 확장성(scalability)을 높이는 데 유리하다. 즉, 서버가 사용자 상태를 유지하지 않기 때문에 어떤 서버로 요청이 가더라도 동일하게 처리할 수 있다.
- 무상태성을 유지하면, 서버 간의 세션 동기화가 필요 없으므로 서버를 자유롭게 추가하거나 제거할 수 있어 수평 확장이 용이하다.
- 특히 CSR 방식의 프론트엔드와 REST API 백엔드로 구성된 애플리케이션에서는 클라이언트가 서버와 데이터를 교환하면서 화면을 렌더링하기 때문에, 서버는 클라이언트의 상태를 기억할 필요 없이 독립적인 요청과 응답을 처리하는 것이 더 효율적이다.
왜 JWT가 무상태성을 유지하는가?
- JWT는 사용자가 로그인한 후 토큰을 클라이언트 측에 저장하고 요청 시마다 토큰을 전송하여 사용자를 인증한다. 이 때문에 서버는 사용자의 상태를 기억할 필요가 없고 매번 토큰의 유효성만 확인하면 되므로 무상태성을 유지할 수 있다.
- 또한, 각 요청이 독립적이기 때문에 서버가 사용자의 상태를 저장할 필요가 없으며, 이는 REST API의 무상태성 원칙과 부합한다.
액세스 토큰 (Access Token)
액세스 토큰은 사용자 인증을 위해 발급되는 단기 토큰으로, 특정 리소스에 접근할 수 있는 권한을 제공하는 데 사용됩니다.
액세스 토큰의 특징
- 단기 유효 기간:
- 액세스 토큰은 보통 몇 분에서 몇 시간 정도의 짧은 유효 기간을 가진다.
- 유효 기간이 짧게 설정되는 이유는, 토큰이 탈취되더라도 이를 사용할 수 있는 시간을 최소화하기 위함이다. 즉, 보안성을 높이기 위한 것이다.
- 사용 목적:
- 액세스 토큰은 클라이언트가 서버에 인증된 요청을 보낼 때 사용된다.
- 클라이언트는 요청 시 Authorization 헤더에 액세스 토큰을 포함하여 서버로 전송한다:
Authorization: Bearer <Access Token>
- 서버는 이 토큰을 받아 서명 검증을 수행하고, 토큰이 유효한 경우 요청을 처리합니다.
- 권한 정보:
- 액세스 토큰에는 사용자에 대한 인증 정보(예: 사용자 ID, 권한, 만료 시간)가 포함되어 있다.
- 이 정보를 바탕으로 서버는 사용자가 해당 요청을 수행할 수 있는 권한이 있는지 판단한다.
- 무상태성 유지:
- 액세스 토큰을 사용하면 **무상태(stateless)**로 인증을 유지할 수 있다. 즉, 서버는 클라이언트의 상태를 기억할 필요 없이, 각 요청마다 전송되는 토큰을 검증하여 인증을 수행한다.
- 이는 RESTful API와 같은 무상태 아키텍처에서 매우 유용하다.
리프레시 토큰 (Refresh Token)
리프레시 토큰은 액세스 토큰이 만료된 이후 새로운 액세스 토큰을 발급받기 위한 장기 유효 기간의 토큰입니다.
리프레시 토큰의 특징
- 장기 유효 기간:
- 리프레시 토큰은 보통 몇 주에서 몇 달의 긴 유효 기간을 가집니다.
- 액세스 토큰보다 훨씬 긴 유효 기간을 가짐으로써, 사용자가 자주 로그인하지 않아도 연속적인 사용자 경험을 제공할 수 있도록 한다.
- 사용 목적:
- 액세스 토큰이 만료되었을 때, 클라이언트는 리프레시 토큰을 서버로 전송하여 새로운 액세스 토큰을 발급받는다.
- 이렇게 함으로써 사용자는 다시 로그인하지 않고도 새로운 액세스 토큰을 통해 인증 상태를 유지할 수 있다.
- 안전한 저장:
- 리프레시 토큰은 보통 더 높은 수준의 보안을 요구한다. 클라이언트가 리프레시 토큰을 탈취당하면, 공격자는 새로운 액세스 토큰을 지속적으로 발급받아 사용자의 리소스에 접근할 수 있기 때문이다.
- 따라서 리프레시 토큰은 HttpOnly 쿠키와 같은 안전한 저장소에 보관하는 것이 권장된다.
- 서버 측 저장:
- 리프레시 토큰은 서버 측에서 관리하는 경우도 많습니다. 서버에서 리프레시 토큰을 데이터베이스나 메모리에 저장하여 관리하며, 클라이언트가 새로운 액세스 토큰을 요청할 때 서버에서 리프레시 토큰의 유효성을 검증하고 새로운 액세스 토큰을 발급한다.
- 서버 측에 리프레시 토큰을 저장하면, 토큰의 폐기나 리프레시 토큰 무효화 등 보안 기능을 좀 더 쉽게 관리할 수 있다.
'SpringBoot' 카테고리의 다른 글
CQRS 에 관해서 정리 (0) | 2025.01.03 |
---|---|
@PostConstruct (0) | 2024.10.31 |
Controller - service 리팩토링 (0) | 2024.04.16 |