SpringBoot

JWT (JSON Web Token)

작소율 2024. 12. 4. 17:55

🔑 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) 형식으로 만들어진다.

언제, 왜 사용하는가?

  1. 권한부여 -> 해당 토큰을 사용해 권한을 통한 허용된 경로를 체크하고 서비스에 엑세스가 가능하다.
  2. 정보교환 -> 당사자 간에 정보를 공개키, 개인키를 활용하는 방식을 사용하여 signature를 생성하여 발신자가 누구인지를 알 수 있도록하여 정보를 안전하게 전송할 수 있다. (무결성, 신뢰성 보장)
  3. 무상태성을 유지 -> 세션 기반 인증 방식은 사용자의 로그인 정보를 서버 측에서 관리하기 때문에, 서버에 부하가 발생할 수 있다.  JWT를 사용하면 무상태성을 유지하면서 인증된 사용자의 자격을 증명할 수 있다. 즉, 사용자가 누구인지 기억할 필요 없이 토큰에 있는 정보에 접근 권한이 있는지만 체크하면 된다

무결성은 데이터가 허가되지 않은 방식으로 변경되지 않았음을 보장하는 속성

 

왜 무상태성을 유지해야 할까?

  • **무상태성(stateless)**은 서버의 확장성(scalability)을 높이는 데 유리하다. 즉, 서버가 사용자 상태를 유지하지 않기 때문에 어떤 서버로 요청이 가더라도 동일하게 처리할 수 있다.
  • 무상태성을 유지하면, 서버 간의 세션 동기화가 필요 없으므로 서버를 자유롭게 추가하거나 제거할 수 있어 수평 확장이 용이하다.
  • 특히 CSR 방식의 프론트엔드와 REST API 백엔드로 구성된 애플리케이션에서는 클라이언트가 서버와 데이터를 교환하면서 화면을 렌더링하기 때문에, 서버는 클라이언트의 상태를 기억할 필요 없이 독립적인 요청과 응답을 처리하는 것이 더 효율적이다.

왜 JWT가 무상태성을 유지하는가?

  • JWT는 사용자가 로그인한 후 토큰을 클라이언트 측에 저장하고 요청 시마다 토큰을 전송하여 사용자를 인증한다. 이 때문에 서버는 사용자의 상태를 기억할 필요가 없고 매번 토큰의 유효성만 확인하면 되므로 무상태성을 유지할 수 있다.
  • 또한, 각 요청이 독립적이기 때문에 서버가 사용자의 상태를 저장할 필요가 없으며, 이는 REST API의 무상태성 원칙과 부합한다.

 

액세스 토큰 (Access Token)

액세스 토큰사용자 인증을 위해 발급되는 단기 토큰으로, 특정 리소스에 접근할 수 있는 권한을 제공하는 데 사용됩니다.

액세스 토큰의 특징

  1. 단기 유효 기간:
    • 액세스 토큰은 보통 몇 분에서 몇 시간 정도의 짧은 유효 기간을 가진다.
    • 유효 기간이 짧게 설정되는 이유는, 토큰이 탈취되더라도 이를 사용할 수 있는 시간을 최소화하기 위함이다. 즉, 보안성을 높이기 위한 것이다.
  2. 사용 목적:
    • 액세스 토큰은 클라이언트가 서버에 인증된 요청을 보낼 때 사용된다.
    • 클라이언트는 요청 시 Authorization 헤더에 액세스 토큰을 포함하여 서버로 전송한다:
      Authorization: Bearer <Access Token>
    • 서버는 이 토큰을 받아 서명 검증을 수행하고, 토큰이 유효한 경우 요청을 처리합니다.
  3. 권한 정보:
    • 액세스 토큰에는 사용자에 대한 인증 정보(예: 사용자 ID, 권한, 만료 시간)가 포함되어 있다.
    • 이 정보를 바탕으로 서버는 사용자가 해당 요청을 수행할 수 있는 권한이 있는지 판단한다.
  4. 무상태성 유지:
    • 액세스 토큰을 사용하면 **무상태(stateless)**로 인증을 유지할 수 있다. 즉, 서버는 클라이언트의 상태를 기억할 필요 없이, 각 요청마다 전송되는 토큰을 검증하여 인증을 수행한다.
    • 이는 RESTful API와 같은 무상태 아키텍처에서 매우 유용하다.

리프레시 토큰 (Refresh Token)

리프레시 토큰액세스 토큰이 만료된 이후 새로운 액세스 토큰을 발급받기 위한 장기 유효 기간의 토큰입니다.

리프레시 토큰의 특징

  1. 장기 유효 기간:
    • 리프레시 토큰은 보통 몇 주에서 몇 달의 긴 유효 기간을 가집니다.
    • 액세스 토큰보다 훨씬 긴 유효 기간을 가짐으로써, 사용자가 자주 로그인하지 않아도 연속적인 사용자 경험을 제공할 수 있도록 한다.
  2. 사용 목적:
    • 액세스 토큰이 만료되었을 때, 클라이언트는 리프레시 토큰을 서버로 전송하여 새로운 액세스 토큰을 발급받는다.
    • 이렇게 함으로써 사용자는 다시 로그인하지 않고도 새로운 액세스 토큰을 통해 인증 상태를 유지할 수 있다.
  3. 안전한 저장:
    • 리프레시 토큰은 보통 더 높은 수준의 보안을 요구한다. 클라이언트가 리프레시 토큰을 탈취당하면, 공격자는 새로운 액세스 토큰을 지속적으로 발급받아 사용자의 리소스에 접근할 수 있기 때문이다.
    • 따라서 리프레시 토큰은 HttpOnly 쿠키와 같은 안전한 저장소에 보관하는 것이 권장된다.
  4. 서버 측 저장:
    • 리프레시 토큰은 서버 측에서 관리하는 경우도 많습니다. 서버에서 리프레시 토큰을 데이터베이스메모리에 저장하여 관리하며, 클라이언트가 새로운 액세스 토큰을 요청할 때 서버에서 리프레시 토큰의 유효성을 검증하고 새로운 액세스 토큰을 발급한다.
    • 서버 측에 리프레시 토큰을 저장하면, 토큰의 폐기리프레시 토큰 무효화 등 보안 기능을 좀 더 쉽게 관리할 수 있다.

'SpringBoot' 카테고리의 다른 글

CQRS 에 관해서 정리  (0) 2025.01.03
@PostConstruct  (0) 2024.10.31
Controller - service 리팩토링  (0) 2024.04.16