카카오계정과 함께 로그아웃하기를 구현하면서 발생한
무한 redirect loop
여러가지 이유들이 있겠지만
상황 1
1) A 페이지에서 자동으로 B 페이지로 이동
2) B 페이지에서 자동으로 A 페이지로 이동
상황 2
1) A 페이지에서 A 페이지를 자동으로 호출
보통 이런 상황 때문이라고 한다
어느 부분에서 문제가 발생하는지 보기 위해 디버깅을 실행했다
사실 학원에서 디버깅에 대한 것을 배우고 직접 사용해보기는 했지만
전체적으로 잘 모르는 상황에서 배웠던 거라 디버깅 하는 방법을 완벽히 숙지하지는 못하고 있어
처음부터 찾아보면서 해봤다
먼저 LogoutController의 logout메소드에서 실행을 해봤다
@RequestMapping(value = "/kakao/logout", method = RequestMethod.GET)
public String logout() {
// 카카오와 함께 로그아웃하는 URL
String logoutUrl = "https://kauth.kakao.com/oauth/logout";
// 카카오 애플리케이션의 REST API 키
String clientId = "1f9ba236274cc877d8d549827331eb10";
// 서비스의 로그아웃 Redirect URI
String redirectUri = "http://localhost:8080/kakao/logout";
// GET 요청에 필요한 파라미터 설정 및 URL 인코딩
try {
clientId = URLEncoder.encode(clientId, "UTF-8");
redirectUri = URLEncoder.encode(redirectUri, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// GET 요청에 필요한 파라미터 설정
String params = "?client_id=" + clientId + "&logout_redirect_uri=" + redirectUri;
// RestTemplate을 이용한 GET 요청
RestTemplate restTemplate = new RestTemplate();
System.out.println("로그아웃111");
// 요청 헤더 설정
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 요청 엔티티 생성
HttpEntity<String> entity = new HttpEntity<>(headers);
// RestTemplate을 사용하여 GET 요청 보내기
restTemplate.exchange(logoutUrl + params, HttpMethod.GET, entity, String.class);
// 카카오에서 제공하는 Redirect URI로 서비스 측으로 리디렉션
return "redirect:" + logoutUrl + params;
}
이렇게 로그 찍을 것을 추가하고 restTemplate.exchange() 의 위에 브레이크 포인트를 걸어줬다

variables에 찍힌 것을 보아 메소드가 예상대로 실행되고 있음을 알 수 있었다
또, console에도 로그가 찍혔다
그러면 logoutRedirect를 디버깅 해봐야한다
// 카카오에서 제공하는 Redirect URI로 요청이 들어왔을 때의 처리
@RequestMapping(value = "/kakao/logout/redirect", method = RequestMethod.GET)
public String logoutRedirect(HttpSession session) {
// 서비스 측에서는 해당 Redirect URI로 요청이 들어왔을 때, 사용자의 세션을 무효화하고 원하는 작업을 수행
session.invalidate();
System.out.println("로그아웃222");
return "redirect:/user/sign-in-view";
}
이 코드에서 System.out.println("로그아웃222");이 곳에 브레이크 포인트를 걸고 실행해봤더니
console에 로그아웃 1이 루프 돌고있는것이 보였다

그렇다면 logout에서 logoutRedirect로 못가고 logout 메소드가 반복적으로 호출되고 있다는 건데,,
코드를 계속 읽어봤다
그런데 이 logoutController를 작성하기 전에
kakaodeveloper에 미리 정해뒀던 로그아웃 redirect uri인 /kakao/logout이 갑자기 눈에 들어왔다
아래 redirect 요청 받는 value는 /kakao/logout/redirect 인데 ..?
클라이언트가 /kakao/logout으로 로그아웃 요청을 보내면
로그아웃이 완료 된 후에 kakao/logout/redirect로 카카오가 사용자를 redirect 시켜야 하는건데
redirect uri를 kakao/logout 으로 설정해두니 계속 무한 루프가 돈 것이었나보다
그래서 로그아웃 redirect uri를 수정해줬다
LogoutController.java
@Controller
public class LogoutController {
@RequestMapping(value = "/kakao/logout", method = RequestMethod.GET)
public String logout(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
// 카카오와 함께 로그아웃하는 URL
String logoutUrl = "https://kauth.kakao.com/oauth/logout";
// 카카오 애플리케이션의 REST API 키
String clientId = "1f9ba236274cc877d8d549827331eb10";
// 서비스의 로그아웃 Redirect URI
String redirectUri = "http://localhost:8080/kakao/logout/redirect";
// GET 요청에 필요한 파라미터 설정 및 URL 인코딩
try {
clientId = URLEncoder.encode(clientId, "UTF-8");
redirectUri = URLEncoder.encode(redirectUri, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// GET 요청에 필요한 파라미터 설정
String params = "?client_id=" + clientId + "&logout_redirect_uri=" + redirectUri;
// RestTemplate을 이용한 GET 요청
RestTemplate restTemplate = new RestTemplate();
// 요청 헤더 설정
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 요청 엔티티 생성
HttpEntity<String> entity = new HttpEntity<>(headers);
// RestTemplate을 사용하여 GET 요청 보내기
restTemplate.exchange(logoutUrl + params, HttpMethod.GET, entity, String.class);
// 카카오에서 제공하는 Redirect URI로 서비스 측으로 리디렉션
return "redirect:" + logoutUrl + params;
}
// 카카오에서 제공하는 Redirect URI로 요청이 들어왔을 때의 처리
@RequestMapping(value = "/kakao/logout/redirect", method = RequestMethod.GET)
public String logoutRedirect(HttpSession session) {
// 서비스 측에서는 해당 Redirect URI로 요청이 들어왔을 때, 사용자의 세션을 무효화하고 원하는 작업을 수행
session.invalidate();
return "redirect:/user/sign-in-view";
}
}
이 코드로 카카오 로그아웃을 실행했더니 정상적으로 카카오 계정과 함께 로그아웃이 완료되었다
카카오 로그인까지는 지난주에 구현을 완료 했지만
로그인보다 간단하다고 들었던 카카오 로그아웃에도 시간이 많이 소요되었다
일반 로그아웃 보다는 카카오계정과 함께 로그아웃을 꼭 구현해보고싶은 마음에
시간이 많이 지체 된 것같다
소셜로그인중에서 제일 쉽다고들 하는 카카오로그인을
이해하고 구현하기까지 아주 오래 잡고 있었지만
결국 구현을 완료 했다는 것에 뿌듯하다..!