24.02.25

서린·2024년 2월 25일

혼자개발

목록 보기
53/82

일반 로그인과 카카오 로그인을 다른 방법으로 로그아웃을 해야한다
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";
	}

}

이대로 실행 했더니 로그아웃 버튼을 눌러도 로그아웃이 정상적으로 완료되지 않았다

0개의 댓글