JWT 도입 4편 - Access Token 재발급

민선규·2024년 7월 17일
0

JAVA

목록 보기
22/25
post-thumbnail

JWT

저번 시간에는 Refresh Token 발급에 대해 구현을 하고 테스트를 진행하였습니다. 이번에는 Refresh Token을 활용해서 Access Token을 재발급 받는 로직을 구현하고 테스트를 진행해보겠습니다.

AuthController

AuthController는 재발급을 처리하는 기능이 있습니다. AuthService의 refresh 함수를 실행해 줍니다.

refresh 함수에서 반환되는 AuthResponseDto를 ResponseEntity에 감싸서 리턴을 하고 있습니다.

@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
public class AuthController implements AuthControllerDocs {

    private final AuthService authService;

    @GetMapping("/refresh")
    public ResponseEntity<AuthResponseDto> refresh(HttpServletRequest request, HttpServletResponse response) {
        AuthResponseDto authResponseDto = authService.refresh(request, response);
        return ResponseEntity.ok(authResponseDto);
    }
}

AuthService

AuthService는 재발급 요청을 처리하는 기능을 가지고 있습니다. 각 로직에 대한 설명은 주석으로 작성하였습니다.

(현재 예외 처리를 IllegalArgumentException로 일괄 처리하였는데 적절한 예외 처리로 수정을 해야합니다.)

@Service
@RequiredArgsConstructor
public class AuthService {

    private final JwtUtil jwtUtil;
    private final MemberService memberService;
    @Value("${spring.jwt.accessToken_expiration_time}")
    private Long accessTokenExpiredMs;
    @Value("${spring.jwt.refreshToken_expiration_time}")
    private Long refreshTokenExpiredMs;
    
    public AuthResponseDto refresh(HttpServletRequest request, HttpServletResponse response) {
    
        String refreshToken = null;
        
        //요청에 저장되어 있는 쿠키를 배열 형태로 가져옵니다.
        Cookie[] cookies = request.getCookies();
        //쿠키가 null이면 IllegalArgumentException을 발생시킵니다.
        if(cookies == null){
            throw new IllegalArgumentException("잘못된 요청입니다.");
        }

		//쿠키에 저장된 Refresh Token 값을 가져옵니다.
        for(Cookie cookie : cookies){
            if(cookie.getName().equals("refresh")){
                refreshToken = cookie.getValue();
                break;
            }
        }

		//Refresh Token의 값이 null이면 IllegalArgumentException을 발생시킵니다.
        if(refreshToken == null){
            throw new IllegalArgumentException("잘못된 요청입니다.");
        }

		//Refresh Token가 만료되었는지 확인하고 만료되었다면 IllegalArgumentException을 발생시킵니다.
        try {
            jwtUtil.isExpired(refreshToken);
        }
        catch (ExpiredJwtException e){
            throw new IllegalArgumentException("잘못된 요청입니다.");
        }

		//Refresh Token의 category 값을 가져옵니다.
        String category = jwtUtil.getCategory(refreshToken);
        //category가 refresh가 아닌 경우에 IllegalArgumentException을 발생시킵니다.
        if(!category.equals("refresh")){
            throw new IllegalArgumentException("잘못된 요청입니다.");
        }

		//Refresh Token의 MemberResponseDto 값을 가져옵니다.
        MemberResponseDto memberResponseDto = jwtUtil.getMemberResponseDto(refreshToken);

		//MemberResponseDto를 기반으로 새로운 Access Token을 만듭니다.
        String accessToken = jwtUtil.createJwt("access", memberResponseDto, accessTokenExpiredMs);

		//AuthResponseDto에 Access Token 값을 넣어서 생성합니다.
        AuthResponseDto authResponseDto = AuthResponseDto.builder()
                .accessToken(accessToken)
                .build();

		//AuthResponseDto을 반환합니다.
        return authResponseDto;
    }
}

TEST

이제 Access Token 재발급을 테스트 해보겠습니다.

첫 번째 요청을 통해 Access Token을 발급받고 쿠키로 받은 Refresh Token을 Cookie에 담아서 두 번째 요청을 한 결과 새로운 Access Token을 발급받은 것을 확인할 수 있었습니다.

여기까지 하면 JWT의 주요 기능은 구현을 했다고 생각합니다. 다음 포스트에서는 Refresh Token의 보안을 높일 수 있는 로직을 작성해보겠습니다!

0개의 댓글

관련 채용 정보