-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[feat] #17 oauth2 관련_CustomOAuth2User, OAuthAttributes, Service, user…
…Info 생성
- Loading branch information
Showing
7 changed files
with
217 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
src/main/java/com/wedit/weditapp/global/oauth2/domain/CustomOAuth2User.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.wedit.weditapp.global.oauth2.domain; | ||
|
||
import com.wedit.weditapp.domain.shared.MemberRole; | ||
import com.wedit.weditapp.domain.shared.MemberStatus; | ||
import lombok.Getter; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.oauth2.core.user.DefaultOAuth2User; | ||
|
||
import javax.management.relation.Role; | ||
import java.util.Collection; | ||
import java.util.Map; | ||
|
||
@Getter | ||
public class CustomOAuth2User extends DefaultOAuth2User { | ||
private String email; | ||
private MemberRole role; | ||
private MemberStatus status; | ||
public CustomOAuth2User(Collection<? extends GrantedAuthority> authorities, | ||
Map<String, Object> attributes, String nameAttributeKey, | ||
String email, MemberRole role, MemberStatus status) { | ||
super(authorities, attributes, nameAttributeKey); | ||
this.email = email; | ||
this.role = role; | ||
this.status = status; | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/main/java/com/wedit/weditapp/global/oauth2/dto/OAuthAttributes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.wedit.weditapp.global.oauth2.dto; | ||
|
||
import com.wedit.weditapp.global.oauth2.userInfo.KakaoOAuth2UserInfo; | ||
import com.wedit.weditapp.global.oauth2.userInfo.OAuth2UserInfo; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import org.springframework.security.core.userdetails.User; | ||
|
||
import java.util.Map; | ||
import java.util.UUID; | ||
|
||
@Getter | ||
public class OAuthAttributes { | ||
|
||
private String nameAttributeKey; // OAuth2 로그인 진행 시 키가 되는 필드 값, PK와 같은 의미 | ||
private OAuth2UserInfo oauth2UserInfo; // 소셜 타입별 로그인 유저 정보(닉네임, 이메일, 프로필 사진 등등) | ||
|
||
@Builder | ||
private OAuthAttributes(String nameAttributeKey, OAuth2UserInfo oauth2UserInfo) { | ||
this.nameAttributeKey = nameAttributeKey; | ||
this.oauth2UserInfo = oauth2UserInfo; | ||
} | ||
|
||
public static OAuthAttributes ofKakao(String userNameAttributeName, Map<String, Object> attributes) { | ||
return OAuthAttributes.builder() | ||
.nameAttributeKey(userNameAttributeName) | ||
.oauth2UserInfo(new KakaoOAuth2UserInfo(attributes)) | ||
.build(); | ||
} | ||
|
||
// 이건 나중에 서비스나 엔티티 생성 로직에서 처리하는 게 더 나음 | ||
// public User toEntity(SocialType socialType, OAuth2UserInfo oauth2UserInfo) { | ||
// return User.builder() | ||
// .socialType(socialType) | ||
// .socialId(oauth2UserInfo.getId()) | ||
// .email(UUID.randomUUID() + "@socialUser.com") | ||
// .nickname(oauth2UserInfo.getNickname()) | ||
// .imageUrl(oauth2UserInfo.getImageUrl()) | ||
// .role(Role.GUEST) | ||
// .build(); | ||
// } | ||
|
||
} |
93 changes: 93 additions & 0 deletions
93
src/main/java/com/wedit/weditapp/global/oauth2/service/CustomOAuth2UserService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.wedit.weditapp.global.oauth2.service; | ||
|
||
import com.wedit.weditapp.domain.member.domain.Member; | ||
import com.wedit.weditapp.domain.member.domain.repository.MemberRepository; | ||
import com.wedit.weditapp.global.error.ErrorCode; | ||
import com.wedit.weditapp.global.error.exception.CommonException; | ||
import com.wedit.weditapp.global.oauth2.domain.CustomOAuth2User; | ||
import com.wedit.weditapp.global.oauth2.dto.OAuthAttributes; | ||
import com.wedit.weditapp.global.oauth2.userInfo.KakaoOAuth2UserInfo; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.security.core.authority.SimpleGrantedAuthority; | ||
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; | ||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; | ||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; | ||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||
import org.springframework.security.oauth2.core.user.OAuth2User; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.Collections; | ||
import java.util.Map; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> { | ||
|
||
private final MemberRepository memberRepository; | ||
|
||
@Override | ||
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { | ||
log.info("CustomOAuth2UserService.loadUser() - 카카오 OAuth2 로그인 요청 진입"); | ||
|
||
// 1. DefaultOAuth2UserService를 사용해 카카오에서 사용자 정보(attributes)를 가져옴 | ||
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService(); | ||
OAuth2User oAuth2User = delegate.loadUser(userRequest); | ||
|
||
// 2. registrationId, userNameAttributeName 추출 (카카오인 경우) | ||
String registrationId = userRequest.getClientRegistration().getRegistrationId(); | ||
String userNameAttributeName = userRequest | ||
.getClientRegistration().getProviderDetails() | ||
.getUserInfoEndpoint().getUserNameAttributeName(); | ||
|
||
// 3. 카카오 사용자 정보(attributes) 가져오기 | ||
Map<String, Object> attributes = oAuth2User.getAttributes(); | ||
|
||
// 카카오 전용 OAuthAttributes 생성 (ofKakao) | ||
OAuthAttributes extractAttributes = | ||
OAuthAttributes.ofKakao(userNameAttributeName, attributes); | ||
|
||
// 4. DB에서 Member 조회 or 생성 | ||
Member member = getOrSaveMember(extractAttributes); | ||
|
||
// 5. DefaultOAuth2User를 상속한 CustomOAuth2User 반환 + USER로 설정 | ||
return new CustomOAuth2User( | ||
Collections.singleton(new SimpleGrantedAuthority("ROLE_" + member.getRole().name())), | ||
attributes, | ||
extractAttributes.getNameAttributeKey(), | ||
member.getEmail(), | ||
member.getRole(), | ||
member.getStatus() | ||
); | ||
} | ||
|
||
// DB에서 카카오 소셜 회원 식별자를 통해 Member 조회 | ||
// 없으면 새로 생성 후 저장 | ||
private Member getOrSaveMember(OAuthAttributes attributes) { | ||
KakaoOAuth2UserInfo kakaoInfo = (KakaoOAuth2UserInfo) attributes.getOauth2UserInfo(); | ||
|
||
String nickname = validateOrSetDefaultNickname(kakaoInfo.getNickname()); | ||
String email = validateOrThrowEmail(kakaoInfo.getEmail()); | ||
|
||
return memberRepository.findByEmail(email).orElseGet(() -> saveNewMember(email, nickname)); | ||
} | ||
|
||
// 닉네임 검증 메서드 | ||
private String validateOrSetDefaultNickname(String nickname) { | ||
return (nickname == null || nickname.isEmpty()) ? "카카오사용자" : nickname; | ||
} | ||
|
||
// 이메일 검증 메서드 | ||
private String validateOrThrowEmail(String email) { | ||
if (email == null || email.isEmpty()) { | ||
throw new CommonException(ErrorCode.EMAIL_NOT_PROVIDED); | ||
} | ||
return email; | ||
} | ||
|
||
// 새 멤버 저장 메서드 | ||
private Member saveNewMember(String email, String nickname) { | ||
return memberRepository.save(Member.createUser(email, nickname)); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/com/wedit/weditapp/global/oauth2/userInfo/KakaoOAuth2UserInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.wedit.weditapp.global.oauth2.userInfo; | ||
|
||
import java.util.Map; | ||
|
||
public class KakaoOAuth2UserInfo extends OAuth2UserInfo { | ||
|
||
public KakaoOAuth2UserInfo(Map<String, Object> attributes) { | ||
super(attributes); | ||
} | ||
|
||
@Override | ||
public String getId() { | ||
return String.valueOf(attributes.get("id")); | ||
} | ||
|
||
@Override | ||
public String getNickname() { | ||
Map<String, Object> account = (Map<String, Object>) attributes.get("kakao_account"); | ||
if (account == null) return null; | ||
|
||
Map<String, Object> profile = (Map<String, Object>) account.get("profile"); | ||
if (profile == null) return null; | ||
|
||
return (String) profile.get("nickname"); | ||
} | ||
|
||
@Override | ||
public String getEmail() { | ||
Map<String, Object> account = (Map<String, Object>) attributes.get("kakao_account"); | ||
if (account == null) return null; | ||
|
||
return (String) account.get("email"); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/wedit/weditapp/global/oauth2/userInfo/OAuth2UserInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.wedit.weditapp.global.oauth2.userInfo; | ||
|
||
import java.util.Map; | ||
|
||
public abstract class OAuth2UserInfo { | ||
|
||
protected Map<String, Object> attributes; | ||
|
||
public OAuth2UserInfo(Map<String, Object> attributes) { | ||
this.attributes = attributes; | ||
} | ||
|
||
// 소셜 식별 값 : 카카오 - "id" | ||
public abstract String getId(); | ||
|
||
public abstract String getNickname(); | ||
|
||
public abstract String getEmail(); | ||
} |