이번에는 리프레시 토큰을 이용하여 토큰을 재발급 받는 과정을 정리하자!!
@Operation(summary = "access&refresh 토큰 재발급", description = "access토큰 만료되면 refresh 토큰을 이용하여 재발급하는 API")
@PostMapping("/reissue")
public ResponseEntity<RefreshTokenResponseDto> reissue(HttpServletRequest httpServletRequest) {
String refreshToken = httpServletRequest.getHeader("Authorization-Refresh");
TokenDto tokenDto = memberService.reissue(refreshToken);
return ResponseEntity.ok()
.header("Authorization", tokenDto.getAccessToken())
.header("Authorization-Refresh",tokenDto.getRefreshToken())
.body(RefreshTokenResponseDto.builder()
.message("accessToken 과 refreshToken이 재발급 성공하셨습니다")
.memberId(tokenDto.getMemberId())
.build());
}
client에서 리프레시 토큰을 받는다. Redis에 있는 리프레시 토큰과 비교하고 새로 엑세스 토큰과 리프레쉬 토큰을 발급받고 client에게 header에 담아서 보내준다.
@Transactional
public TokenDto reissue(String refreshToken) {
log.info("재발급서비스 진입!!!");
if (!jwtTokenProvider.validateToken(refreshToken)) {
throw new CustomException(HttpStatus.BAD_REQUEST, 403, "토큰에 문제 생겼어요");
}
String id = Jwts.parser().setSigningKey(secretKey.getBytes())
.parseClaimsJws(refreshToken).getBody().getId();
Optional<Member> findMember = memberRepository.findById(id);
memberValidator.checkMember(findMember, id);
String redisRefreshToken = redisTemplate.opsForValue().get(findMember.get().getId());
tokenValidator.checkRedisRefreshToken(refreshToken, redisRefreshToken);
String newAccessToken = jwtTokenProvider.createAccessToken(findMember.get().getId());
String newRefreshToken = jwtTokenProvider.createRefreshToken(findMember.get().getId());
jwtTokenProvider.storeRefreshToken(findMember.get().getId(), newRefreshToken);
return TokenDto.builder()
.accessToken(newAccessToken)
.refreshToken(newRefreshToken)
.memberId(findMember.get().getId())
.build();
}
일단 리프레시 토큰이 유효성 검사를 한다.
Redis에 해당 리프레시 토큰을 꺼내서 비교하고 새로운 비교하고 새로운 엑세스 토큰과 리프레시 토큰을 만들고 리프레시 토큰은 Redis에 새로 저장한다.
이렇게 해서 카카오 소셜 로그인 구현을 완료했다. 네이버 로그인도 카카오와 비슷하게 구현했다. 이렇게 소셜 로그인을 구현하면서 OAuth 기반 방식을 이해 할 수 있었고 어떻게 JWT 토큰과 Spring Security를 이용하여 인증 인가하는 방법을 알았다.