[Spring Boot] JWT - AccessToken, RefreshToken

EunCheol·2025년 2월 17일

SpringBoot

목록 보기
1/3

들어가기

새로운 프로젝트를 시작하면서 전자정부 프레임워크를 사용해야 해서
기본으로 제공하는 부트템플릿 페이지를 사용했다.
https://github.com/eGovFramework/egovframe-template-simple-backend

해당 부트템플릿 페이지는 JWT를 기반으로 사용자를 검증하는데 JWT토큰을 1개만 사용하는데
유효기간이 다른 JWT 토큰 2개(Acses Token과 Refresh Token)을 따로 두기로 했다.

1. JWT (JSON Web Token)

개념

JWT(JSON Web Token)는 JSON 형식의 데이터를 안전하게 전송하기 위한 토큰 기반 인증 방식이다.
즉, 클라이언트가 로그인하면 서버는 JWT를 생성하여 클라이언트에게 발급하고, 클라이언트는 이후 요청마다 이 토큰을 포함하여 인증을 수행한다.

구조

JWT는 Header, Payload, Signature 세 부분으로 구성된다.

① Header (헤더)

토큰의 타입과 해싱 알고리즘 정보를 포함한다.

alg: 사용할 암호화 알고리즘 (예: HS256, RS256)
typ: 토큰 타입 (JWT)

{
  "alg": "HS256",
  "typ": "JWT"
}

② Payload (페이로드, 토큰 본문)

사용자 정보(Claims)를 포함하며, 이 데이터를 기반으로 인증을 수행한다.

sub: 토큰의 주체 (사용자 ID)
iat: 토큰 발급 시간 (Issued At)
exp: 토큰 만료 시간 (Expiration)
role: 사용자의 권한 정보

 {
  "sub": "user123",
  "name": "홍길동",
  "iat": 1708156800,
  "exp": 1708160400,
  "role": "USER"
}

③ Signature (서명)

서버에서 JWT가 변조되지 않았음을 보장하기 위해 사용하는 서명(Signature) 부분이다.
HMAC SHA256 또는 RSA 등의 알고리즘을 사용하여 생성된다.

JWT는 최종적으로 아래와 같이 .(점)으로 구분된 문자열 형태이다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6Iu2NvOydtCIsImlhdCI6MTcwODE1NjgwMCwiZXhwIjoxNzA4MTYwNDAwLCJyb2xlIjoiVVNFUiJ9.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

2. Access Token과 Refresh Token

Access Token과 Refresh Token은 JWT 기반 인증 시스템에서 중요한 역할을 하는 두 가지 유형의 토큰이다. 이 두 토큰은 서로 다른 목적을 가지고 있으며, 함께 사용되어 보안성과 사용자 경험을 향상시킨다.

Access Token

정의

Access Token은 사용자가 인증을 받은 후, 서버가 클라이언트에게 발급하는 토큰이다. 이 토큰은 클라이언트가 보호된 리소스에 접근할 수 있도록 허용한다.

특징

  • 유효 기간: Access Token은 일반적으로 짧은 유효 기간(예: 15분에서 1시간)을 가진다. 이는 보안성을 높이기 위한 조치로, 토큰이 유출되더라도 짧은 시간 내에 만료된다.
  • 사용 용도: API 요청 시 Authorization 헤더에 포함되어 서버에 전달된다. 서버는 이 토큰을 검증하여 요청을 처리한다.
  • 구조: JWT 형식으로 인코딩되어 있으며, 사용자 정보와 권한을 포함할 수 있다.

Refresh Token

정의

Refresh Token은 Access Token의 유효 기간이 만료된 후, 새로운 Access Token을 발급받기 위해 사용되는 토큰이다. 이 토큰은 클라이언트가 지속적으로 인증 상태를 유지할 수 있도록 돕는다.

특징

  • 유효 기간: Refresh Token은 일반적으로 긴 유효 기간(예: 몇 주 또는 몇 달)을 가진다. 이는 사용자가 자주 로그인하지 않고도 서비스를 이용할 수 있도록 하기 위함이다.
  • 사용 용도: Access Token이 만료되었을 때, 클라이언트는 Refresh Token을 사용하여 새로운 Access Token을 요청한다. 이 과정에서 Refresh Token이 유효한지 검증된다.
  • 구조: Refresh Token도 JWT 형식으로 인코딩될 수 있지만, 일반적으로 Access Token보다 더 많은 정보를 포함하지 않는다.

왜 Access Token과 Refresh Token을 따로 두는가?

Acess Token 한계
엑세스 토큰을 단독 사용시 재발급 시 로그인을 해야함.
만료시간을 짧게하면 재로그인을 많이 해야하고, 길게하면 공격자로부터 토큰을 탈취당했을때 더 위험함.

Refresh Token 도입
Refresh Token을 사용하여 Access Token을 갱신하여 재로그인을 보다 덜 적게 가능.
Access Token의 만료시간을 짧게 함으로써 탈취 시 문제를 조금이나마 위험방지 낮춤.
사용자가 자주 로그인할 필요 없이, Refresh Token을 통해 새로운 Access Token을 발급받아 서비스를 지속적으로 이용할 수 있음.

Refresh Token 탈취를 당한다면 그건 어쩔수 없다고한다..
이를 예방하기위한 방식이 있다고 한다.

RTR(Refresh Token Rotation)
Access Token가 갱신할때 Refresh Token도 같이 갱신시켜버리는 방식
(Refresh Token Rotation : https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation)
시스템에도 해당 방식으로 적용하기 위해 둘다 같이 토큰 발급 되도록 했다.

프로세스 적용

  1. 사용자 로그인: 사용자가 로그인 정보를 입력하고 서버에 요청을 보낸다.
  2. 로그인 검증: 서버는 사용자의 로그인 정보를 확인하고, 성공하면 인증을 위한 토큰을 생성한다.
  3. 토큰 생성: 서버는 Access Token과 Refresh Token을 생성한후 Access Token만 클라이언트에 반환하며 Access Token과 ReFresh Token은 DB에 저장한다.
  4. 클라이언트 요청: 클라이언트는 Access Token을 포함하여 보호된 리소스에 대한 요청을 보낸다.
  5. 토큰 검증: 서버는 요청에 포함된 Access Token을 검증하여 유효성을 확인한다.
  6. 리소스 접근: 토큰이 유효하면 서버는 요청한 리소스를 클라이언트에 제공한다.
  7. 토큰 만료: Access Token이 만료되면 클라이언트는 DB에 저장된 Refresh Token을 조회한다.
  8. 새로운 Access Token 발급: 서버는 Refresh Token을 검증하고, 새로운 Access Token와 Refresh Token 생성하여 클라이언트에는 Access Token을 반환하고 DB에는 Access Token와 Refresh Token를 둘 다 업데이트한다. Refresh Token이 유효하지 않은경우에는 401 반환한다.

궁금사항

Access Token 만료시 클라이언트 API 재요청? or 서버에서 자동으로 재발급
일부는 Access Token 만료된후에 서버가 401로 반환하여 클라이언트가 Refresh Token을 헤더에 넣어서 API 재요청하는 케이스가 있는데, 본인은 서버에서 재발급을하고 응답헤더에 담아서 API결과값과 함께 보내주었다.

GPT는 다음과 같은 답변이었다.

👉 너의 환경(전자정부 프레임워크 기반)에서는 보안이 중요한 만큼,
💡 클라이언트가 Refresh Token을 직접 요청하는 방식이 적절해 보임.
추가적으로 Refresh Token Rotation(갱신 시 새로운 Refresh Token 발급) 적용을 고려하면 더 안전한 인증 시스템을 구축할 수 있어. 🚀

그렇다고한다..

참고 및 출처

https://junior-datalist.tistory.com/352
https://brunch.co.kr/@jinyoungchoi95/1
https://velog.io/@chuu1019/Access-Token%EA%B3%BC-Refresh-Token%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%A0%EA%B9%8C
https://puleugo.tistory.com/154

2개의 댓글

comment-user-thumbnail
2025년 2월 18일

짱머싯다 너의코드🚀

답글 달기
comment-user-thumbnail
2025년 2월 27일

짱머싯다 너의코드🚀

답글 달기