일반 로그인과 카카오 로그인을 다른 방법으로 로그아웃을 해야한다
user 테이블에 카카오 로그인 사용자가 함께 저장되어서 userName으로 같이 쓰이고있어
session에 kakaoUserName을 새로 추가했다
기존 header.jsp의 사용자 나타내는 부분
<div class="d-flex justify-content-end pt-2 mr-4">
<c:if test="${not empty userName}">
<span>${userName}님 안녕하세요!</span>
<a href="/user/sign-out" class="ml-2">로그아웃</a>
</c:if>
<c:if test="${empty userName}">
<a href="/user/sign-in-view" class="menu-login text-white">로그인</a>
</c:if>
</div>
수정 후
kakaoController.java
@GetMapping("/callback")
public String kakaoCallback(String code, HttpSession session) {
//생략---------------
//가입자 혹은 비가입자 체크 해서 처리
Optional<UserEntity> originUserEntity = userBO.getUserEntityByName(kakaoUser.getName());
if (originUserEntity.isPresent()) { // 이미 가입된 회원인 경우
// 해당 회원으로 로그인 처리
System.out.println("기존 회원입니다-----------------");
UserEntity loggedInUser = originUserEntity.get();
session.setAttribute("userId", loggedInUser.getId());
session.setAttribute("userName", loggedInUser.getName());
session.setAttribute("userLoginId", loggedInUser.getLoginId());
session.setAttribute("kakaoUserName", kakaoProfile.getProperties().getNickname());
// 로그인 성공 메시지 반환
return "redirect:/home/home-list-view";
} else { // 비가입자인 경우
// 회원가입 처리
userBO.addKakaoUser(kakaoUser);
// 회원가입 완료 메시지 반환
return "redirect:/home/home-list-view";
}
}
}
<div class="d-flex justify-content-end pt-2 mr-4">
<c:choose>
<!-- 카카오 로그인 사용자인 경우 -->
<c:when test="${not empty kakaoUserName}">
<span>${kakaoUserName}님 안녕하세요!</span>
<a href="/kakao/logout" class="ml-2">카카오 로그아웃</a>
</c:when>
<!-- 일반 로그인 사용자인 경우 -->
<c:otherwise>
<c:if test="${not empty userName}">
<span>${userName}님 안녕하세요!</span>
<a href="/user/sign-out" class="ml-2">로그아웃</a>
</c:if>
</c:otherwise>
</c:choose>
<c:if test="${empty userName and empty kakaoUserName}">
<a href="/user/sign-in-view" class="menu-login text-white">로그인</a>
</c:if>
</div>
kakaoUserName으로 일반로그인 사용자와 카카오로그인 사용자를 나누고
실행해보니 에러가 발생했다

There was an unexpected error (type=Internal Server Error, status=500).
<h3>Validation error messages from TagLibraryValidator for [c] in [/WEB-INF/jsp/include/header.jsp]</h3><p>34: Illegal text inside "c:choose" tag: "<!-- 카카...".</p><p>37: Illegal text inside "c:choose" tag: "<!-- 일반...".</p>
<c:choose> 태그 내에 주석이 들어가서 발생한 것으로 생각되어서 주석을 지워줬다
<c:choose>는 조건에 따라 분기하는 태그라서 주석을 사용할 수 없다고 한다
주석을 지워 수정하니 에러는 해결되었다
일반로그인을 실행해보니 로그인, 사용자 이름, 로그아웃이 모두 잘 되었다
kakaoController.java
//카카오로그인 코드 생략 ---------------------
@RequestMapping("/logout")
public String logout(HttpSession session) {
// 카카오 API를 사용하여 카카오 계정 연결을 끊음
disconnectKakaoAccount(session);
// 서버에서 사용자의 세션을 제거
session.invalidate();
// 로그아웃 완료 후 로그인 페이지로 리다이렉트
return "redirect:/user/sign-in-view";
}
//카카오 연결 끊기
private void disconnectKakaoAccount(HttpSession session) {
// 세션에서 oauthToken 가져오기
OAuthToken oauthToken = (OAuthToken) session.getAttribute("oauthToken");
System.out.println(oauthToken);
// oauthToken이 존재하면 카카오 로그아웃 요청 보내기
if (oauthToken != null) {
// Kakao API에 요청을 보내어 카카오 로그아웃 실행
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + oauthToken.getAccess_token());
RestTemplate restTemplate = new RestTemplate();
try {
restTemplate.exchange(
"https://kapi.kakao.com/v1/user/logout",
HttpMethod.POST,
new HttpEntity<>(headers),
String.class
);
} catch (RestClientException e) {
// 예외 처리
System.err.println("Kakao 로그아웃 실패: " + e.getMessage());
}
}
}
카카오로그인을 실행해보니 로그인과 사용자 이름, 로그아웃이 잘 되었지만
카카오 계정과 함께 로그아웃을 구현하고 싶었는데
자동으로 로그인이 되고있었다
kakakodeveloper 에서 로그아웃 하는 방법을 다시 확인해봤는데
카카오계정과 함께 로그아웃을 하려면 url은 'https://kauth.kakao.com/oauth/logout'으로 get요청을 보내야 하고 'client_id'와 'logout_redirect_uri'를 각각 설정해 GET 요청에 필요한 파라미터로 추가하여 카카오와 함께 로그아웃하는 URL을 호출해야 하는 것이었다..
그래서 새로운 LogoutController.java 클래스를 생성해줬다
@Controller
public class LogoutController {
@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 요청에 필요한 파라미터 설정
String params = "?client_id=" + clientId
+ "&logout_redirect_uri=" + redirectUri;
// RestTemplate을 이용한 GET 요청
RestTemplate restTemplate = new RestTemplate();
// 요청 헤더 설정
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
// 요청 엔티티 생성
HttpEntity<String> entity = new HttpEntity<>(headers);
// RestTemplate을 사용하여 GET 요청 보내기
ResponseEntity<String> response = restTemplate.exchange(logoutUrl + params, HttpMethod.GET, entity, String.class);
return "redirect:/user/sign-in-view";
}
}
이대로 실행 했더니 로그아웃 버튼을 눌러도 로그아웃이 정상적으로 완료되지 않았다