feat: oauth 로그인 구현

This commit is contained in:
kimjunseo
2021-07-23 02:23:56 +09:00
parent 82c20475a0
commit a636e5694b
4 changed files with 136 additions and 1 deletions

View File

@@ -0,0 +1,49 @@
package com.example.oauthspringsecurity.domain;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
public enum OAuthAttributes {
GITHUB("github", (attributes) -> {
return new UserProfile(
String.valueOf(attributes.get("id")),
(String) attributes.get("name"),
(String) attributes.get("email"),
(String) attributes.get("avatar_url")
);
}),
GOOGLE("google", (attributes) -> {
return new UserProfile(
String.valueOf(attributes.get("sub")),
(String) attributes.get("name"),
(String) attributes.get("email"),
(String) attributes.get("picture")
);
}),
NAVER("naver", (attributes) -> {
Map<String, Object> response = (Map<String, Object>) attributes.get("response");
return new UserProfile(
(String) response.get("id"),
(String) response.get("name"),
(String) response.get("email"),
(String) response.get("profile_image")
);
});
private final String registrationId;
private final Function<Map<String, Object>, UserProfile> of;
OAuthAttributes(String registrationId, Function<Map<String, Object>, UserProfile> of) {
this.registrationId = registrationId;
this.of = of;
}
public static UserProfile extract(String registrationId, Map<String, Object> attributes) {
return Arrays.stream(values())
.filter(provider -> registrationId.equals(provider.registrationId))
.findFirst()
.orElseThrow(IllegalArgumentException::new)
.of.apply(attributes);
}
}

View File

@@ -0,0 +1,35 @@
package com.example.oauthspringsecurity.domain;
public class UserProfile {
private final String oauthId;
private final String name;
private final String email;
private final String imageUrl;
public UserProfile(String oauthId, String name, String email, String imageUrl) {
this.oauthId = oauthId;
this.name = name;
this.email = email;
this.imageUrl = imageUrl;
}
public Member toMember() {
return new Member(oauthId, name, email, imageUrl, Role.USER);
}
public String getOauthId() {
return oauthId;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getImageUrl() {
return imageUrl;
}
}

View File

@@ -0,0 +1,11 @@
package com.example.oauthspringsecurity.repository;
import java.util.Optional;
import com.example.oauthspringsecurity.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findByOauthId(String id);
}

View File

@@ -1,15 +1,55 @@
package com.example.oauthspringsecurity.service;
import java.util.Collections;
import java.util.Map;
import com.example.oauthspringsecurity.domain.Member;
import com.example.oauthspringsecurity.domain.OAuthAttributes;
import com.example.oauthspringsecurity.domain.UserProfile;
import com.example.oauthspringsecurity.repository.MemberRepository;
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.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
@Service
public class OAuthService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final MemberRepository memberRepository;
public OAuthService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
return null;
OAuth2UserService delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest); // OAuth 서비스(github, google, naver)에서 가져온 유저 정보를 담고있음
String registrationId = userRequest.getClientRegistration()
.getRegistrationId(); // OAuth 서비스 이름(github, naver, google)
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails()
.getUserInfoEndpoint().getUserNameAttributeName();
Map<String, Object> attributes = oAuth2User.getAttributes();
UserProfile userProfile = OAuthAttributes.extract(registrationId, attributes);
Member member = saveOrUpdate(userProfile);
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(member.getRoleKey())),
attributes,
userNameAttributeName);
}
private Member saveOrUpdate(UserProfile userProfile) {
Member member = memberRepository.findByOauthId(userProfile.getOauthId())
.map(m -> m.update(userProfile.getName(), userProfile.getEmail(), userProfile.getImageUrl()))
.orElse(userProfile.toMember());
return memberRepository.save(member);
}
}