Dev/SpringBoot

Spring Boot 3 kakao oauth2 Login 구현 - 2

VIPeveloper 2025. 7. 15. 09:59
728x90
반응형

어제에 이어 controller 부분을 작성해보려 한다.

이전 포스팅은 아래 참고

 

2025.07.14 - [Dev/SpringBoot] - Spring Boot 3 kakao oauth2 Login 구현 - 1

 

 

1️⃣ 로그아웃 설정 ( OAuthController.java )

- 클래스 명은 적당히 원하는 것으로 지으면 된다.

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Slf4j
@Controller
@RequiredArgsConstructor
public class OauthController {

    @Value("${spring.security.oauth2.client.registration.kakao.client-id}")
    String restApiKey;

    @GetMapping("kakaoLogout")
    public String kakaoLogout(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession(false);
        if (session != null) {

            // ✅ Spring Security 인증 정보 제거
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (auth != null) {
                new SecurityContextLogoutHandler().logout(request, response, auth);
            }

            StringBuffer url = new StringBuffer();
            url.append("https://kauth.kakao.com/oauth/logout");
            url.append("?client_id=");
            url.append(restApiKey);
            url.append("&");
            url.append("logout_redirect_uri=http://localhost:12341");
            return "redirect:" + url;
        }


        // ✅ 로그아웃 후 리다이렉트
        return "redirect:/";
    }
}

 

2️⃣ Member Entity 관련 설정

// Member.java

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Comment;

import java.time.LocalDateTime;

@Getter
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "member_id")
    private Long id;

    private String OAuthId;
    private String OAuthType;

    @Comment("권한")
    @Enumerated(EnumType.STRING)
    private MemberStatus memberStatus = MemberStatus.USER;

    private LocalDateTime createdAt;
}
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface MemberRepository extends JpaRepository<Member,Long> {
    Optional<Member> findByOAuthIdAndOAuthType(String oauthId, String oauthType);
}

 

- 사용자 상태는 아래와 같이 두었다.

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum MemberStatus {
    ADMIN("관리자"),
    USER("사용자"),
    USER_BAN("금지계정"),
    USER_DORMANT("휴면계정");
    private final String name;
}

 

- 간단하게 어드민 계정 접속 테스트 해볼 수 있는 controller 도 생성했다.

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Slf4j
@Controller
@RequiredArgsConstructor
@RequestMapping("admin")
public class AdminController {

    @GetMapping("index")
    public String index() {
        return "admin/index";
    }

}

 

 

3️⃣ 페이지 생성

- 메인 페이지

- 어드민 페이지

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    <meta charset="UTF-8">
    <title>로그인 상태 확인</title>
</head>
<body>

<h2>🧾 로그인 상태 확인 페이지</h2>

<!-- 로그인 여부에 따라 분기 -->
<div sec:authorize="isAuthenticated()">
    <p>✅ 로그인된 사용자입니다.</p>
    <p>사용자 이름: <span sec:authentication="name"></span></p>
    <p>권한: <span sec:authentication="authorities"></span></p>
    <a th:href="@{/kakaoLogout}">🔓 로그아웃</a>
</div>

<div sec:authorize="isAnonymous()">
    <p>❌ 로그인되지 않았습니다.</p>
    <a th:href="@{/oauth2/autorization/kakao}">🔑 카카오 로그인하기</a>
</div>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
admin hello world
</body>
</html>

 

앱 구조

앱의 구조는 아래와 같다. 참고하면 될듯 하다.

 

 

 

테스트 시나리오 화면

로그인 하지 않았을 때는 아래와 같이 보인다.

로그인 하면 아래와 같이 보인다.

 

로그아웃 시 아래 페이지가 나온다.

 

 

 

어드민 페이지 접근 시 아래와 같이 403 에러가 난다.

 

결론

- 카카오 로그인을 이용해 로그인, 로그아웃, 로그인 시 자동 회원 가입 등의 기능을 표현할 수 있는 기초 기능을 만들었다.

- 네이버나 구글로 확장하면 될듯.

728x90
반응형