요 며칠간 refresh token을 어떻게 프로젝트에 적용 시킬까 고민을 열심히 하고 수많은 포스팅을 들락 거렸다.
머리를 싸매고, 약간 뒹굴거리며 생각해낸 방법
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) {
User user = ((UserDetailsImpl) authResult.getPrincipal()).getUser();
String userId = user.getUserId();
// 토큰 생성시 유효기간 차이를 두고 생성
String token = jwtService.createToken(userId);
String refreshToken = jwtService.createRefreshToken(userId);
// 헤더의 이름을 변경해서 2가지 토큰을 response header에 추가
response.addHeader(JwtService.AUTHORIZATION_HEADER, token);
response.addHeader(JwtService.REFRESH_TOKEN_HEADER, refreshToken);
user.setRefreshToken(refreshToken);
userRepository.save(user);
}
//JwtAuthorizationFilter.java
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException {
...
String userRefreshToken = jwtService.substringToken(user.getRefreshToken());
String refreshToken = jwtService.getRefreshJwtFromHeader(req);
log.info("User's Refresh Token: " + userRefreshToken);
log.info("response's Refresh Token: " + refreshToken);
// 유저가 보유한 토큰과 httpservlet의 토큰이 같은지 비교
if (userRefreshToken.equals(refreshToken)) {
// 토큰이 만료된 경우
if (jwtService.isTokenExpired(tokenValue)) {
// 리프레시 토큰이 유효한 경우, 새로운 토큰 생성
if (!jwtService.isRefreshTokenExpired(userRefreshToken)) {
jwtService.createToken(user.getUserId());
System.out.println("jwtService.createToken(user.getUserId()) = " + jwtService.createToken(user.getUserId()));
jwtService.createRefreshToken(user.getUserId());
log.info("새로운 토큰이 생성되었습니다.");
setAuthentication(claims.getSubject());
filterChain.doFilter(req, res);
} else {
// 리프레시 토큰도 만료된 경우
throw new IllegalArgumentException("다시 재로그인해주세요");
}
} else {
// 토큰이 유효한 경우
setAuthentication(claims.getSubject());
}
} else {
throw new IllegalArgumentException("토큰의 정보가 일치하지 않습니다.");
}
}
...