Skip to content

Commit

Permalink
feat kookmin-sw#2 - OAuth2UserService 기능 구현
Browse files Browse the repository at this point in the history
로그인 시 카카오 혹은 네이버에서 받아온 사용자 정보를 이용하여 회원가입이 안되어있는 사용자의 경우 save 시키고, 이미 가입된 회원이라면 SharedPostPrincipal 객체 반환하도록 함
  • Loading branch information
leejh7 committed Mar 10, 2024
1 parent 32e44e6 commit 1e4f192
Showing 1 changed file with 25 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package org.capstone.maru.service;
package org.capstone.maru.security;

import java.util.Collections;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.capstone.maru.domain.MemberAccount;
import org.capstone.maru.dto.CustomOAuth2User;
import org.capstone.maru.dto.OAuthAttributes;
import org.capstone.maru.dto.SocialType;
import org.capstone.maru.repository.MemberAccountRepository;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.capstone.maru.security.constant.SocialType;
import org.capstone.maru.service.MemberAccountService;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
Expand All @@ -20,70 +14,42 @@
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {

private final MemberAccountRepository userRepository;
private static final String NAVER = "naver";
private static final String KAKAO = "kakao";
private final MemberAccountService memberAccountService;

@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {

OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);

/**
* userRequest에서 registrationId 추출 후 registrationId으로 SocialType 저장
* http://localhost:8080/oauth2/authorization/kakao에서 kakao가 registrationId
* userNameAttributeName은 이후에 nameAttributeKey로 설정된다.
*/
String registrationId = userRequest.getClientRegistration().getRegistrationId();
SocialType socialType = getSocialType(registrationId);
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails().getUserInfoEndpoint()
.getUserNameAttributeName(); // OAuth2 로그인 시 키(PK)가 되는 값
Map<String, Object> attributes = oAuth2User.getAttributes(); // 소셜 로그인에서 API가 제공하는 userInfo의 Json 값(유저 정보들)

// socialType에 따라 유저 정보를 통해 OAuthAttributes 객체 생성
OAuthAttributes extractAttributes = OAuthAttributes.of(socialType, userNameAttributeName,
attributes);

MemberAccount createdUser = getUser(extractAttributes, socialType);

// DefaultOAuth2User를 구현한 CustomOAuth2User 객체를 생성해서 반환
return new CustomOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(createdUser.getRole().getKey())),
attributes,
extractAttributes.getNameAttributeKey(),
createdUser.getEmail()
OAuth2Response extractAttributes = OAuth2Response.of(
socialType,
oAuth2User.getAttributes()
);
}

private SocialType getSocialType(String registrationId) {
if (NAVER.equals(registrationId)) {
return SocialType.NAVER;
}
if (KAKAO.equals(registrationId)) {
return SocialType.KAKAO;
}
return null;
String memberId = getMemberId(registrationId, extractAttributes);

return memberAccountService
.searchMember(memberId)
.map(SharedPostPrincipal::from)
.orElseGet(() ->
SharedPostPrincipal.from(
memberAccountService.saveUser(
memberId,
extractAttributes.email(),
extractAttributes.nickname()
)
)
);
}

private MemberAccount getUser(OAuthAttributes attributes, SocialType socialType) {
MemberAccount findUser = userRepository.findBySocialTypeAndSocialId(socialType,
attributes.getOauth2UserInfo().getId()).orElse(null);

if (findUser == null) {
return saveUser(attributes, socialType);
}
return findUser;
private SocialType getSocialType(String registrationId) {
return SocialType.of(registrationId);
}

/**
* OAuthAttributes의 toEntity() 메소드를 통해 빌더로 User 객체 생성 후 반환 생성된 User 객체를 DB에 저장 : socialType,
* socialId, email, role 값만 있는 상태
*/
private MemberAccount saveUser(OAuthAttributes attributes, SocialType socialType) {
MemberAccount createdUser = attributes.toEntity(socialType, attributes.getOauth2UserInfo());
return userRepository.save(createdUser);
private String getMemberId(String registrationId, OAuth2Response oAuth2Response) {
return registrationId + "_" + oAuth2Response.id();
}

}

0 comments on commit 1e4f192

Please sign in to comment.