Spring

JSON Web Token

변위니 2025. 1. 7. 02:32

 

프로젝트 중에 JWT를 사용하여서 잘 몰라서.. 공부하고자

 

 

 

HTTP는 웹에서 클라이언트와 서버 간의 통신을 가능하게 하는 규칙이다. 하지만 통신 후 연결을 유지하지 않고, 상태를 저장하는지 않기 때문에, 사용자 매번 인증 과정을 반복해야 하는 불편함이 있다. 

 

상태를 유지하기 위해 쿠키와 세션 방식이 나왔다. 하지만 쿠키는 보안에 취약하고 세션은 접속자가 많아질 경우 서버에 부하가 증가하게 된다. 그리고 다중 서버 시 세션 공유 문제가 발생할 수 있다. 

 

이러한 문제를 해결하기 위해 RESTful API와 같은 stateless 아키텍처가 요구하는 인증 방식으로 JWT(JSON Web Token)가 등장했다. JWT는 사용자 정보를 담고 있는 JSON 형식의 토큰으로, 서버가 상태를 저장할 필요 없이 각 요청에서 토큰을 검증하여 사용자 인증을 처리할 수 있다. 이 방식은 확장성과 보안성이 뛰어나고 다양한 플랫폼 간 호환성이 좋아서 많이 사용된다. 



 

 


JWT (JSON Web Token)

정보를 JSON 형태로 클라이언트에 저장하고 서버는 해당 토큰을 검증하여 인증을 처리하는 방식이다.

토큰 안에 미리 인증에 필요한 정보를 넣어두면 매 요청마다 서버와 통신할 필요가 없다. 이로 인해 서버 부하와 같은 문제를 해결할 수 있다.

 

 


JWT를 활용한 로그인 프로세스

1. 클라이언트 : 인증 요청
사용자가 아이디와 비밀번호를 입력하여 서버에 인증 요청을 보낸다.

2. 서버 : 사용자 정보 유효성 확인
서버는 데이터베이스와 비교하여 사용자의 정보가 유효한지 확인한다.

3. 서버 : JWT 생성
인증에 성공하면 서버는 사용자의 정보를 기반으로 JWT를 생성한다.

4. 클라이언트 : JWT 반환
서버는 생성된 JWT를 클라이언트에 반환한다.

5. JWT 저장
클라이언트는 받은 JWT를 세션이나 쿠키에 저장한다.

 

 

 

인증 필요한 자원에 접근시

1. 클라이언트 : 인증이 필요한 API 요청
인증이 필요한 API를 호출할 때, Authorization헤더에 JWT를 포함시킨다.

2. 서버 : JWT 검증 후 리소스 제공

JWT가 유효한지 검증 후, 유효한 경우 자원을 사용자에게 반환한다.




 


JWT 구조

헤더, 페이로드, 서명 세 부분으로 구성된다.

  • 헤더는 토큰의 타입과 해싱 알고리즘 정보를 담는다.
  • 페이로드는 클레임이라고 불리는 정보 조각을 포함한다. 클레임은 토큰에 추가할 정보를 의미하며 사용자 ID, 권한 정보등이 포함된다.
    디코딩을 통해 들어있는 정보를 확인할 수 있기 때문에 민감한 정보는 포함하면 안된다.
  • 서명은 토큰을 인코딩하거나 유효성 검증을 위해서 사용되는 부분으로, 헤더와 페이로드를 합친 후 Secret Key 사용하여 생성한다.

헤더

  • 타입해싱 알고리즘으로 구성된다.
  • 해싱 알고리즘으로는 보통 HMAC SHA256 혹은 RSA 가 사용되며, 이 알고리즘은 서명 부분에서 사용된다.
  • 예 : {“alg”: “HS256”, “typ”: “JWT”}

페이로드

  • 실제 데이터가 담긴 부분으로 여러 개의 클레임을 포함한다.
  • 클레임은 JWT에 담을 정보 조각으로 사용자ID, 권한, 만료 시간 등이 포함된다.
  • 쉽게 디코딩될 수 있기때문에, 민감한 정보(비밀번호)는 포함하지 않는 것이 좋다.

서명

  • 헤더의 인코딩 값과 페이로드의 인코딩 값을 합친 후 비밀키를 사용해 생성한다.
  • 토큰의 무결성을 검증하는 용도로 사용된다.
  • 서버는 클라이언트로부터 받은 토큰을 검증하기 위해 서명 부분을 해싱 알고리즘과 비밀키로 다시 생성하고 이를 클라이언트가 전달한 서명과 비교하여, 일치하면 인증이 유효한 것으로 판단한다.

이러한 구조로 JWT는 클라이언트와 서버 간의 인증 정보를 안전하게 전송하고, 서버는 상태를 저장하지 않고 사용자를 인증할 수 있다.

 

 

JWT는 발급될 때 유효기간을 설정하는데, 한 번 발급되면 만료될 때까지 변경할 수 없기 때문에, 짧게 설정되면 로그인을 계속 해야해서 사용자에게 불편을 줄 수 있고, 길게 설정하면 보안이 취약해질 수 있다. 이러한 문제를 해결하기 위해 Access Token과 Refresh Token을 함께 사용한다. 

 

Access Token은 짧은 유효기간을 가져 탈취 시 피해를 줄이고, Refresh Token은 새로운 Access Token을 발급하는 데 사용된다.



 

 

 

 


Access Token과 Refresh Token

Access Token은 사용자가 서버에 요청할 때 전달되는 토큰으로, 짧은 유효기간을 갖는다. 사용자의 인증과 권한을 검증하는 데 사용되며, 토큰이 만료되면 클라이언트는 더 이상 이 토큰으로 요청할 수 없다. 유효기간이 짧아 탈취되더라도 피해가 제한적이다.

 

Refresh Token은 Access Token이 만료되었을 때 새로운 Access Token을 발급하는 데 사용되며, 유효기간이 길기 때문에 안전하게 관리해야 한다. Access Token이 만료되었을 때 클라이언트는 Refresh Token을 서버로 보내 Access Token을 새로 발급받는다.

 

 


 

Access Token / Refresh Token 흐름

  1. 사용자가 이메일, 패스워드를 입력하여 로그인한다.

  2. 사용자가 로그인하면, 서버는 클라이언트에게 두 개의 토큰을 발급한다
    Access Token, Refresh Token

  3. Access Token을 사용한 요청
    사용자는 Access Token과 함께 요청을 보낸다.
    서버는 Access Token을 검증하여 유효하면 요청을 처리한다.

  4. Access Token 발급
    Access Token이 만료되면 클라이언트는 Refresh Token을 서버에 전달하여 새로운 Access Token을 요청한다.
    서버는 Refresh Token 검증 후, 새로운 Access Token을 발급하여 클라이언트에 반환한다.

  5. 로그아웃 또는 Refresh Token 만료
    * 로그아웃 시, 서버는 Access/Refresh Token을 무효화하는 로직을 실행한다. (블랙리스트)
    * Refresh Token의 유효기간이 만료 시, 사용자는 다시 로그인을 통해 토큰을 재발급 받아야 한다.



Access Token과 Refresh Token을 함께 사용하는 이유

Access Token을 짧은 유효기간을 갖도록 해서, 탈취되더라도 그 피해를 최소화할 수 있다. 하지만 짧은 유효기간으로 인해 Access Token이 자주 만료되기 때문에, 매번 재발급받야아 하는 번거로움이 있다. 매번 재발급 받아야하는 번거로움을 줄이기 위해 유효시간이 긴 Refresh Token을 이용하여 Access Token이 만료되었을 때, 새로운 Access Token을 발급받을 수 있도록한다.

이를 통 짧은 유효기간의 Access Token으로 보안을 강화하고, 긴 유효기간의 Refresh Token을 사용하여 사용자 편의성을 유지할 수 있다.



Refresh Token은 발급되면 장기간 사용할 수 있기 때문에, 탈취되면 지속적으로 엑세스 토큰을 발급할 수 있어 보안상 위험이 있다. 

이 위험을 줄이기 위한 방법이 Refresh Token Rotation이다.
 

 

 


Refresh Token Rotation

 

Access Token을 요청할 때마다 새로운 Refresh Token을 발급하고, 이전 Refresh Token은 무효화된다.

 

 

RTR 흐름

  1. 액세스 토큰과 리프레시 토큰 발급
    사용자가 처음 로그인하면 서버는 Access/ Refresh Token을 클라이언트에게 발급한다.

  2. 액세스 토큰 재발급
    Access Token이 만료되면, 클라이언트는 Refresh Token을 사용하여 새로운 Access Token을 요청한다. 이때, 서버는 클라이언트에게 새로운 Access Token과 새로운 Refresh Token을 함께 발급해준다.

  3. 이전 리프레시 토큰을 무효
    새로운 Refresh Token이 발급되면 이전 Refresh Token은 즉시 무효화된다.
    따라서 한 번 사용된 리프레시 토큰은 다시 사용할 수 없다.



Refresh Token이 탈취된 경우, 공격자는 해당 토큰으로 새로운 Access Token을 발급받으려 시도할 수 있다.

하지만 Refresh Token Rotation 방식에서는 Refresh Token이 사용될 때마다 새로운 Refresh Token이 발급되고, 이전 토큰은 즉시 무효화되기 때문에 탈취된 토큰을 재사용할 수 없다.

 

 



'Spring' 카테고리의 다른 글

Controller, RestController 어떻게 다를까  (0) 2025.02.02
Spring과 Spring Boot 동작이 어떻게 다른거야~  (1) 2025.01.20
DI(Dependency Injection)  (0) 2025.01.07