Day12. React <-> SpringBoot : Logout 구현하기

2ㅣ2ㅣ·2024년 11월 11일

Project

목록 보기
11/13

개요

클라이언트에서 로그아웃 요청 시 인증 정보를 초기화하고 로그아웃을 처리할 개별 API를 구현하려고 한다. 이 API는 Jwt + Cookie 기반 인증을 사용하는 환경을 고려하여 설계했다.

As-Is

SecurityConfig.logout 메서드는 기본적으로 세션 기반 인증 시스템에서 설계되었기 때문에 Jwt + Cookie로 인증 처리를 하고 있는 내 프로젝트에서는 개별 API를 구현해야 했다.

To-Be

클라이언트측

fetch('http://localhost:8080/member/logout', {
    method: 'POST',
    credentials: 'include',
})
.then(response => {
    if (response.ok) {
        document.cookie = "accessToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
        // localStorage, sessionStorage 초기화
        localStorage.clear();
        sessionStorage.clear();
        // 브라우저 히스토리 초기화
        window.history.replaceState({}, document.title, '/');
        // 홈('/')으로 리다이렉션
        window.location.href = '/';
    }
})
.catch(error => console.error('Logout failed:', error));
  1. 로그아웃 API 호출: credentials: 'include'로 쿠키 포함
  2. 응답 성공 시: 모든 쿠키 삭제 후 홈(/)으로 리다이렉션

서버측

Controller

    @PostMapping("/logout")
    public BaseResponse<Void> logout(
            Principal principal
    ){
        String email = principal.getName();
        return memberService.logout(email);
    }

Principal을 통해 현재 인증된 사용자의 이메일을 추출하여 서비스로 전달한다.

Service

	@Transactional
    public BaseResponse<Void> logout(String email) {
        try {
            Member member = memberRepository.findByEmail(email)
                    .orElseThrow(() -> new CustomRuntimeException(BaseResponseStatus.NOT_FOUND_MEMBER));

            tokenRepository.findByMemberId(member.getId())
                    .ifPresent(token -> tokenRepository.delete(token));

            Cookie expiredAccessToken = createExpiredCookie("accessToken");

            ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpServletResponse response = attr.getResponse();
            if (response != null){
                response.addCookie(expiredAccessToken);
            }
            return new BaseResponse<>(BaseResponseStatus.SUCCESS);
        } catch (Exception e){
            log.error("Logout failed for email : {}", email, e);
            throw new CustomRuntimeException(BaseResponseStatus.INTERNAL_SERVER_ERROR);

        }
    }

회원 검증을 통과하면 토큰을 제거하고 만료쿠키(즉시 만료될 예정의 쿠키)를 발급한다.

createExpiredCookie method

	private Cookie createExpiredCookie(String name) {
        Cookie cookie = new Cookie(name, "");
        cookie.setMaxAge(0); //즉시 만료
        cookie.setPath("/"); // 애플리케이션 전체에 대해 적용
        cookie.setHttpOnly(true);
        cookie.setSecure(true);

        return cookie;
    }

만료 쿠키를 발급하는 메서드이다.

0개의 댓글