상세 컨텐츠

본문 제목

[Spring] JWT(Json Web Token) 정리

Spring/Spring Security

by Chan.94 2024. 8. 15. 13:25

본문

반응형

JWT (Json Web Token)

JWT(Json Web Token)란 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token

토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함된다.

 

JWT는 보통 Spring Security와 같이 사용한다.

Spring Security와 JWT 구현에 대한 내용은 아래 포스팅을 확인하기 바란다.

 

Spring Security 개념 및 Architecture

Spring Security + JWT 인증 (1/2) - JWT 구현

Spring Security + JWT 인증 (2/2) - Spring Security 설정

JWT 탄생배경

전통적인 세션 인증 방식의 경우에는 Stateful 방식이다. 즉, 서버에서 세션에 대한 상태를 알고 있다는 뜻이다.

그렇기에 매 요청마다 서버와 통신을 해야 했고, 이는 곧 많은 트래픽 앞에서 서버 부하의 원인이 되기도 한다.

 

JWT는 이러한 문제점들을 해결하기 위해 등장했고 Stateless인 것이 특징이다.

토큰 안에 미리 인증에 필요한 정보들을 넣어둠으로써 매 요청마다 서버와 통신을 할 필요가 없게 되었다. 

이로 인해 서버 부하와 같은 문제점들을 해결할 수 있게 되었다.


JWT구조

Header, Payload, Signature의 3 부분으로 이루어지며, Json 형태인 각 부분은 Base64로 인코딩 되어 표현된다. 또한 각각의 부분을 이어 주기 위해. 구분자를 사용하여 구분한다.

 

JWT 정보 확인하기

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

Header(헤더)

  • typ : 토큰 타입 지정
  • alg : 알고리즘 방식을 지정하고 서명 및 토큰 검증과 생성에 사용된다.

 

Payload (페이로드)

토큰의 페이로드에는 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨 있다. 
Json(Key/Value) 형태로 다수의 정보를 넣을 수 있다.

클레임은 저장되는 정보에 따라 등록된 클레임(Registered Claims), 공개 클레임(Public Claims), 비공개 클레임(Private Cliams)로 구분된다.

 

등록된 클레임 (Registered Claim)

  • iss: 토큰 발급자(issuer)
  • sub: 토큰 제목(subject)
  • aud: 토큰 대상자(audience)
  • exp: 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 함 ex) 1480849147370
  • nbf: 토큰 활성 날짜(not before), 이 날이 지나기 전의 토큰은 활성화되지 않음
  • iat: 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간을 알 수 있음
  • jti: JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용

공개 클레임 (public claims)

충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 합니다. 충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓습니다.

{
    "https://fvor001.tistory.com": true
}



비공개 클레임 (private claims)

통신을 주고받는 당사자들끼리 협의해서 자유롭게 키와 값을 정할 수 있다.

 

Signature(서명)

Header(헤더) 에서 정의한 알고리즘 방식(alg)을 활용한다.

Header와 Palyoad를 Base64로 인코딩한 값과 서버의 Secret Key를 Header에서 정의한 알고리즘으로 암호화한 값이다.

 

가장 중요한 것은 Secret Key이다.

Header와 Payload는 단순히 인코딩 된 값이기 때문에 제 3자가 Decode 하여 및 조작할 수 있지만, Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없다.
따라서, Signature는 토큰의 위변조 여부를 확인하는데 사용된다.

 


JWT사용 시 고려사항

  • 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있습니다. 따라서 중요한 정보는 페이로드에 담지 않는 것이 좋습니다.
  • 페이로드(Payload) 자체는 암호화 된 것이 아니라 BASE64로 인코딩 된 것이다.
    중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로 중요 데이터를 넣지 않아야 한다. 
  • JWT토큰을 탈취당할 경우 대처가 힘들기에 만료기간을 적절히 짧게 사용해야 한다.
    만료시간을 길게 하지 않기 위해 AccessToken과 RefreshToken을 함께 발행하고 AccessToken의 만료시간을 짧게 발행하는 방법을 사용하기도 한다. 하지만, RefreshToken도 탈취당할 위험이 있다.

JWT 동작 원리

1. 클라이언트에서 서버로 ID/PW로 로그인을 요청한다.
2. 서버에서 검증 과정을 거쳐 해당 유저가 존재하면, Access Token + Refresh Token을 발급한다.
3. 클라이언트는 요청 헤더에 2번에서 발급받은 Access Token 을 포함하여 API를 요청한다.

 

4. 클라이언트에서 보낸 Access Token의 만료시간이 지났다면, Access Token이 만료 되었다는 응답을 전달

5. 만료 응답을 받은 클라이언트는 Access Token을 재발급 받기위해 저장 공간에 저장해두었던, Refresh Token을 서버에 전달

6. 서버에서 Refresh Token 검증 후 Access Token과 Refresh Token을 클라이언트에 전달

Access Token

인증된 사용자가 특정 리소스에 접근할 때 사용되는 토큰

  • 클라이언트는 Access Token을 사용하여 인증된 사용자의 신원을 확인하고, 서비스 또는 리소스에 접근
  • 유효 기간이 지나면 만료 (expired)
  • 만료된 경우, 새로운 Access Token을 얻기 위해 Refresh Token 사용

 

Refresh Token

Access Token의 갱신을 위해 사용되는 토큰

  • 일반적으로 Access Token과 함께 발급
  • Access Token이 만료되면 Refresh Token을 사용하여 새로운 Access Token 발급
  • 사용자가 지속적으로 인증 상태를 유지할 수 있도록 도와줌 (매번 로그인 다시 하지 않아도 됨)
  • Access Token보다 긴 유효 기간 가짐

 

RTR (Refresh Token Rotation)

Refresh Token Rotation의 약자로 Refresh Token을 단 한 번만 사용할 수 있도록 하는 것이다.

  1. Access Token 1과 Refresh Token 1을 얻는다.
  2. Refresh Token 1을 사용하여 Access Token 2와 Refresh Token 2를 얻는다.
  3. Refresh Token 2를 사용하여 Access Token 3와 Refresh Token 3를 얻는다.
  4. 이 과정을 계속 반복한다.
반응형

관련글 더보기

댓글 영역

>