|
1 | | -package org.capstone.maru.service; |
| 1 | +package org.capstone.maru.security; |
2 | 2 |
|
3 | | -import java.util.Collections; |
4 | | -import java.util.Map; |
5 | 3 | import lombok.RequiredArgsConstructor; |
6 | | -import org.capstone.maru.domain.MemberAccount; |
7 | | -import org.capstone.maru.dto.CustomOAuth2User; |
8 | | -import org.capstone.maru.dto.OAuthAttributes; |
9 | | -import org.capstone.maru.dto.SocialType; |
10 | | -import org.capstone.maru.repository.MemberAccountRepository; |
11 | | -import org.springframework.security.core.authority.SimpleGrantedAuthority; |
| 4 | +import org.capstone.maru.security.constant.SocialType; |
| 5 | +import org.capstone.maru.service.MemberAccountService; |
12 | 6 | import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; |
13 | 7 | import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; |
14 | 8 | import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; |
|
20 | 14 | @Service |
21 | 15 | public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> { |
22 | 16 |
|
23 | | - private final MemberAccountRepository userRepository; |
24 | | - private static final String NAVER = "naver"; |
25 | | - private static final String KAKAO = "kakao"; |
| 17 | + private final MemberAccountService memberAccountService; |
26 | 18 |
|
27 | 19 | @Override |
28 | 20 | public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { |
29 | | - |
30 | 21 | OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService(); |
31 | 22 | OAuth2User oAuth2User = delegate.loadUser(userRequest); |
32 | 23 |
|
33 | | - /** |
34 | | - * userRequest에서 registrationId 추출 후 registrationId으로 SocialType 저장 |
35 | | - * http://localhost:8080/oauth2/authorization/kakao에서 kakao가 registrationId |
36 | | - * userNameAttributeName은 이후에 nameAttributeKey로 설정된다. |
37 | | - */ |
38 | 24 | String registrationId = userRequest.getClientRegistration().getRegistrationId(); |
39 | 25 | SocialType socialType = getSocialType(registrationId); |
40 | | - String userNameAttributeName = userRequest.getClientRegistration() |
41 | | - .getProviderDetails().getUserInfoEndpoint() |
42 | | - .getUserNameAttributeName(); // OAuth2 로그인 시 키(PK)가 되는 값 |
43 | | - Map<String, Object> attributes = oAuth2User.getAttributes(); // 소셜 로그인에서 API가 제공하는 userInfo의 Json 값(유저 정보들) |
44 | | - |
45 | | - // socialType에 따라 유저 정보를 통해 OAuthAttributes 객체 생성 |
46 | | - OAuthAttributes extractAttributes = OAuthAttributes.of(socialType, userNameAttributeName, |
47 | | - attributes); |
48 | 26 |
|
49 | | - MemberAccount createdUser = getUser(extractAttributes, socialType); |
50 | | - |
51 | | - // DefaultOAuth2User를 구현한 CustomOAuth2User 객체를 생성해서 반환 |
52 | | - return new CustomOAuth2User( |
53 | | - Collections.singleton(new SimpleGrantedAuthority(createdUser.getRole().getKey())), |
54 | | - attributes, |
55 | | - extractAttributes.getNameAttributeKey(), |
56 | | - createdUser.getEmail() |
| 27 | + OAuth2Response extractAttributes = OAuth2Response.of( |
| 28 | + socialType, |
| 29 | + oAuth2User.getAttributes() |
57 | 30 | ); |
58 | | - } |
59 | 31 |
|
60 | | - private SocialType getSocialType(String registrationId) { |
61 | | - if (NAVER.equals(registrationId)) { |
62 | | - return SocialType.NAVER; |
63 | | - } |
64 | | - if (KAKAO.equals(registrationId)) { |
65 | | - return SocialType.KAKAO; |
66 | | - } |
67 | | - return null; |
| 32 | + String memberId = getMemberId(registrationId, extractAttributes); |
| 33 | + |
| 34 | + return memberAccountService |
| 35 | + .searchMember(memberId) |
| 36 | + .map(SharedPostPrincipal::from) |
| 37 | + .orElseGet(() -> |
| 38 | + SharedPostPrincipal.from( |
| 39 | + memberAccountService.saveUser( |
| 40 | + memberId, |
| 41 | + extractAttributes.email(), |
| 42 | + extractAttributes.nickname() |
| 43 | + ) |
| 44 | + ) |
| 45 | + ); |
68 | 46 | } |
69 | 47 |
|
70 | | - private MemberAccount getUser(OAuthAttributes attributes, SocialType socialType) { |
71 | | - MemberAccount findUser = userRepository.findBySocialTypeAndSocialId(socialType, |
72 | | - attributes.getOauth2UserInfo().getId()).orElse(null); |
73 | | - |
74 | | - if (findUser == null) { |
75 | | - return saveUser(attributes, socialType); |
76 | | - } |
77 | | - return findUser; |
| 48 | + private SocialType getSocialType(String registrationId) { |
| 49 | + return SocialType.of(registrationId); |
78 | 50 | } |
79 | 51 |
|
80 | | - /** |
81 | | - * OAuthAttributes의 toEntity() 메소드를 통해 빌더로 User 객체 생성 후 반환 생성된 User 객체를 DB에 저장 : socialType, |
82 | | - * socialId, email, role 값만 있는 상태 |
83 | | - */ |
84 | | - private MemberAccount saveUser(OAuthAttributes attributes, SocialType socialType) { |
85 | | - MemberAccount createdUser = attributes.toEntity(socialType, attributes.getOauth2UserInfo()); |
86 | | - return userRepository.save(createdUser); |
| 52 | + private String getMemberId(String registrationId, OAuth2Response oAuth2Response) { |
| 53 | + return registrationId + "_" + oAuth2Response.id(); |
87 | 54 | } |
88 | | - |
89 | 55 | } |
0 commit comments