JWT Token
1. JWT Token이란?
정보를 JSON 형태로 표현한 token으로 사용자 인증과정에 사용된다.
RFC 7519로 표준화된 규격이다.
JWT는 다음과 같이 구성되며 쉼표를 기준으로 구분된다.
- header 부분은 hash 알고리즘과 token의 type을 가지고 있고 base64로 인코딩된다.
- payload 부분은 token에 담기는 정보로 claim이라고 부른다.
name과 value 쌍으로 이루어져있고 base64로 인코딩된다.
claim으로는 표준 정보를 나타내는 registered claim과 공개적으로 사용되는 정보를 나타내는 public claim과
client와 server에서만 사용되는 정보인 private claim이 있다.
- signature 부분은 header, payload, secret key를 합쳐서 header에 있는 hash 알고리즘으로 암호화한 값이다.
이 값이 비교해서 변조 여부를 판단한다.
2. Access Token과 Refresh Token이란?
access token은 실제 API에 접근해서 리소스를 가져올 때 사용되는 token이다.
짧은 만료 시간을 가진다.
refresh token은 access token이 만료되었을 때 새로운 access token을 발급받기 위해 사용되는 token이다.
access token보다 긴 만료 시간을 가진다.
Refresh Token 적용

1. Access Token과 Refresh Token 발급하기
jwt 구현은 java-jwt 라이브러리를 사용했다.
access token은 만료 시간을 1시간 정도로 짧게 설정하고 refresh token은 1일 정도로 길게 설정한다.
@Component
public class TokenProvider {
public String createAccessToken(String email) {
return JWT.create()
.withClaim("email", email)
.withExpiresAt(new Date(System.currentTimeMillis() + ACCESS_TOKEN_DURATION))
.sign(Algorithm.HMAC512(jwtSecret));
}
public String createRefreshToken() {
return JWT.create()
.withExpiresAt(new Date(System.currentTimeMillis() + REFRESH_TOKEN_DURATION))
.sign(Algorithm.HMAC512(jwtSecret));
}
}
사용자가 로그인을 완료하면 access token과 refresh token을 발급한다.
refresh token은 이후 재발급 과정에서 검증하기 위해 redis에 저장한다.
token을 key로 하고 유저의 email을 value로 저장하는데 ttl은 token의 유효기간으로 설정한다.
@PostMapping("/login")
public BaseResponse<?> login(
@RequestBody @Valid LoginRequestDto requestDto,
HttpSession session
) {
...
var accessToken = tokenProvider.createAccessToken(user.getEmail());
var refreshToken = tokenProvider.createRefreshToken();
userStore.saveRefreshToken(
refreshToken,
user.getEmail(),
tokenProvider.getExpirationDuration(refreshToken)
);
return new BaseResponse<>(
TokenResponseDto.builder()
.accessToken(accessToken)
.refreshToken(refreshToken).build()
);
}
2. Access Token 검증하기
매 요청마다 interceptor를 통해 access token을 추출해서 검증한다.
@RequiredArgsConstructor
@Component
public class Interceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader(ACCESS_TOKEN);
if (StringUtils.isEmpty(token)) {
throw new AuthenticationException(AUTHENTICATION_ERROR);
}
try {
tokenProvider.verifyToken(token);
} catch (Exception e) {
throw new AuthenticationException(AUTHENTICATION_ERROR);
}
return true;
}
}
3. Refresh Token 재발급하기
access token의 만료시간이 지날 경우 refresh token을 사용해서 access token을 다시 재발급 받아야한다.
refresh token이 redis에 저장되어있는지 확인하고 email을 추출한다.
email을 사용해서 다시 access token을 재발급받는다.
@PostMapping("/refresh")
public BaseResponse<?> refresh(
@RequestBody @Valid RefreshTokenRequestDto requestDto
) {
var refreshToken = requestDto.getRefresh_token();
var email = tokenProvider.validateRefreshTokenAndGetEmail(refreshToken);
var newAccessToken = tokenProvider.createAccessToken(email);
return new BaseResponse<>(
TokenResponseDto.builder()
.accessToken(newAccessToken)
.refreshToken(refreshToken).build()
);
}
'프로젝트 > 집안일 관리 시스템' 카테고리의 다른 글
| [유지보수성 개선] 소셜 로그인 기능에 전략 패턴을 적용해보자 (0) | 2025.08.11 |
|---|---|
| [기능 구현] 메모 기능에서 WebSocket을 사용해보자 (0) | 2025.08.05 |
| [성능 개선] Batch 작업을 최적화해보자 (1) | 2024.12.04 |
| [성능 개선] 유니온 쿼리를 개선해보자 (0) | 2024.01.08 |
| [성능 개선] 데이터베이스로 날라가는 쿼리의 수를 줄여보자 (0) | 2024.01.07 |