목차 보기
- ···
- 28.
[멀티캠퍼스] 풀스택 개발자 아카데미 (28) - Spring Boot & JWT(1) - 29.[멀티캠퍼스] 풀스택 개발자 아카데미 (29) - Spring Boot & JWT (2)현재
- 30.
[멀티캠퍼스] 풀스택 개발자 아카데미 (30) - Deployment
지난 글에서는 Spring Boot 환경에서 JWT를 발급하고 검증하는 기본 로직을 구현했다. 하지만 Access Token의 유효 기간을 짧게(30분) 설정했기 때문에, 사용자는 30분마다 로그인이 풀리는 불편함을 겪게 된다.
이번 글에서는 보안과 편의성 두 마리 토끼를 잡기 위한 Refresh Token 도입과, 이를 React(Axios + Redux) 프론트엔드와 매끄럽게 연동하는 방법을 알아본다.
1. Refresh Token 전략이란?
Access Token은 탈취되었을 경우를 대비해 수명을 짧게 가져간다. 대신, 수명이 긴(7일~14일) Refresh Token을 하나 더 발급하여, Access Token이 만료되었을 때 사용자가 다시 로그인할 필요 없이 "투명하게(Silent)" 새로운 Access Token을 발급받도록 하는 전략이다.
- Access Token: 리소스 접근용. 유효기간 짧음 (30분~1시간).
- Refresh Token: 재발급 검증용. 유효기간 김 (1주~2주). DB나 Redis에 저장하여 관리.
2. Backend: 토큰 재발급 API 구현
2.1. Refresh Token 저장소 (Entity)
Refresh Token은 서버가 상태를 관리해야 하므로 DB에 저장해야 한다. (실무에서는 TTL 기능이 있는 Redis를 주로 사용하지만, 여기서는 편의상 RDB(JPA)를 사용한다.)
2.2. 토큰 재발급 (Reissue) 서비스 로직
사용자가 보낸 Access Token과 Refresh Token을 검증하고 새 토큰을 내려주는 로직이다.
2.3. Controller 작성
3. Frontend: React + Axios Interceptor 연동
프론트엔드에서는 매번 API 요청을 보낼 때마다 헤더에 토큰을 넣어야 하고, 토큰 만료 에러(401)가 발생하면 자동으로 재발급 요청을 보내야 한다. 이 복잡한 과정을 컴포넌트마다 작성할 수 없으므로 Axios Interceptor를 사용한다.
3.1. Axios 인스턴스 생성
기본 axios 객체 대신 설정을 커스텀한 인스턴스를 만든다.
3.2. Request Interceptor: 헤더에 토큰 주입
요청이 전송되기 직전에 가로채서 Authorization 헤더를 심어준다. 토큰은 Redux Store나 LocalStorage에서 가져온다.
3.3. Response Interceptor: 401 에러 핸들링 (핵심!)
응답을 받았는데 401 Unauthorized 에러라면, 토큰이 만료된 것이다. 이때 사용자를 튕겨내는 대신 몰래 토큰을 재발급받고 원래 하려던 요청을 다시 실행한다.
3.4. Redux 로그인 액션 (참고)
로그인 성공 시 데이터를 저장하는 부분이다. (Redux Toolkit 예시)
4. 최종 테스트
이제 브라우저를 켜고 테스트를 진행해보자.
- 로그인을 하여 Access Token을 발급받는다.
- (테스트를 위해) DB나 로컬 스토리지의 Access Token 값을 임의로 변경하거나, 서버의 유효 시간을 1분으로 줄여본다.
- 로그인이 필요한 페이지에 접속하거나 새로고침을 한다.
- Network 탭을 확인한다.
- 첫 번째 요청: 401 실패 (빨간색)
- 두 번째 요청:
/token/refresh200 성공 - 세 번째 요청: 원래 하려던 요청 200 성공
이 모든 과정이 사용자 눈에는 "그냥 로딩이 잘 되는 것"처럼 보인다. 이것이 바로 Seamless 한 UX다.
5. 마무리
두 번의 글에 걸쳐 Spring Boot 3.x + Spring Security 6 환경에서의 JWT 인증 시스템을 완벽하게 구축해 보았다.
- 1편: JWT 발급, 검증 필터, Security 설정
- 2편: Refresh Token, Axios Interceptor를 이용한 재발급 자동화
이 구조는 현업에서도 가장 많이 사용하는 표준적인 인증 패턴 중 하나이다. 이 코드를 베이스로 하여 OAuth2(소셜 로그인)를 붙이거나, Redis를 도입해 성능을 최적화하는 방식으로 확장해 나가면 된다.
이제 여러분의 프로젝트에 안전하고 편리한 로그인 시스템을 적용해 볼 수 있다.