From abaa87d6ed9425280a491208832d00d438778ae0 Mon Sep 17 00:00:00 2001 From: 2ghrms Date: Tue, 3 Dec 2024 00:09:37 +0900 Subject: [PATCH] =?UTF-8?q?:sparkles:practice(#10)=20:=20OAuth2=EB=A5=BC?= =?UTF-8?q?=20=ED=99=9C=EC=9A=A9=ED=95=9C=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EC=86=8C=EC=85=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring/build.gradle | 3 + .../security/CustomOAuth2UserService.java | 65 +++++++++++++++++++ .../config/security/SecurityConfig.java | 5 ++ spring/src/main/resources/application.yml | 20 +++++- .../src/main/resources/templates/login.html | 1 + 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 spring/src/main/java/umc/spring/config/security/CustomOAuth2UserService.java diff --git a/spring/build.gradle b/spring/build.gradle index e43400e..6f925af 100644 --- a/spring/build.gradle +++ b/spring/build.gradle @@ -42,6 +42,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.security:spring-security-test' + // Spring Security OAuth2 클라이언트 의존성 추가 + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + //Thymeleaf implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.1.RELEASE' diff --git a/spring/src/main/java/umc/spring/config/security/CustomOAuth2UserService.java b/spring/src/main/java/umc/spring/config/security/CustomOAuth2UserService.java new file mode 100644 index 0000000..fa0fd22 --- /dev/null +++ b/spring/src/main/java/umc/spring/config/security/CustomOAuth2UserService.java @@ -0,0 +1,65 @@ +package umc.spring.config.security; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.user.DefaultOAuth2User; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.stereotype.Service; +import umc.spring.domain.Member; +import umc.spring.domain.enums.Gender; +import umc.spring.domain.enums.Role; +import umc.spring.repository.MemberRepository.MemberRepository; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class CustomOAuth2UserService extends DefaultOAuth2UserService { + + private final MemberRepository memberRepository; + private final PasswordEncoder passwordEncoder; + + @Override + public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { + OAuth2User oAuth2User = super.loadUser(userRequest); + + Map attributes = oAuth2User.getAttributes(); + Map properties = (Map) attributes.get("properties"); + + String nickname = (String) properties.get("nickname"); + String email = nickname + "@kakao.com"; // 임시 이메일 생성 + + // 사용자 정보 저장 또는 업데이트 + Member member = saveOrUpdateUser(email, nickname); + + // 이메일을 Principal로 사용하기 위해 attributes 수정 + Map modifiedAttributes = new HashMap<>(attributes); + modifiedAttributes.put("email", email); + + return new DefaultOAuth2User( + oAuth2User.getAuthorities(), + modifiedAttributes, + "email" // email Principal로 설정 + ); + } + + private Member saveOrUpdateUser(String email, String nickname) { + Member member = memberRepository.findByEmail(email) + .orElse(Member.builder() + .email(email) + .name(nickname) + .password(passwordEncoder.encode("OAUTH_USER_" + UUID.randomUUID())) + .gender(Gender.NONE) // 기본값 설정 + .address("소셜로그인") // 기본값 설정 + .specAddress("소셜로그인") // 기본값 설정 + .role(Role.USER) + .build()); + + return memberRepository.save(member); + } +} diff --git a/spring/src/main/java/umc/spring/config/security/SecurityConfig.java b/spring/src/main/java/umc/spring/config/security/SecurityConfig.java index 0a73e01..3511e8a 100644 --- a/spring/src/main/java/umc/spring/config/security/SecurityConfig.java +++ b/spring/src/main/java/umc/spring/config/security/SecurityConfig.java @@ -25,6 +25,11 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .defaultSuccessUrl("/home", true) .permitAll() ) + .oauth2Login(oauth2 -> oauth2 + .loginPage("/login") + .defaultSuccessUrl("/home", true) + .permitAll() + ) .logout((logout) -> logout .logoutUrl("/logout") .logoutSuccessUrl("/login?logout") diff --git a/spring/src/main/resources/application.yml b/spring/src/main/resources/application.yml index 2b41d0e..f42841e 100644 --- a/spring/src/main/resources/application.yml +++ b/spring/src/main/resources/application.yml @@ -16,4 +16,22 @@ spring: use_sql_comments: true hbm2ddl: auto: update - default_batch_fetch_size: 1000 \ No newline at end of file + default_batch_fetch_size: 1000 + security: + oauth2: + client: + registration: + kakao: + client-authentication-method: client_secret_post + client-id: b520cf6225bb08837856b4bcee2232be + client-secret: 5lBI2OF2hvUBAUHbG2QSUuFeyDCGb6Yn + redirect-uri: http://localhost:8080/login/oauth2/code/kakao + authorization-grant-type: authorization_code + scope: profile_nickname + client-name: Kakao + provider: + kakao: + authorization-uri: https://kauth.kakao.com/oauth/authorize + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + user-name-attribute: id \ No newline at end of file diff --git a/spring/src/main/resources/templates/login.html b/spring/src/main/resources/templates/login.html index e272854..ebc8b52 100644 --- a/spring/src/main/resources/templates/login.html +++ b/spring/src/main/resources/templates/login.html @@ -20,5 +20,6 @@

Login

로그아웃되었습니다.

계정이 없나요? Sign up

+카카오로 로그인 \ No newline at end of file