feat: oauth 로그인 구현
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user