-
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: oauth2 구현 * feat: oauth2 구현에 맞게 security 설정 변경 * feat: 테스트용 controller 생성 * comment: 당장 필요없는 메서드 주석 처리 * refactor: 필요없는 주석 삭제 및 코드 변경 * refactor: 랜덤 아이디 생성 로직 service 단으로 이동 * feat: 추후 가입된 아이디와 social 로그인 연동을 위한 로직 구현 * refactor: tab and swagger tag (cherry picked from commit 7fd4b1a) * 🔥 remove: Test Controller 삭제 * feat: 네이버 소셜로그인 추가 * fix: 빌드 에러 수정 --------- Co-authored-by: baebae02 <bae4614@gmail.com>
- Loading branch information
Showing
14 changed files
with
388 additions
and
44 deletions.
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
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
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
21 changes: 21 additions & 0 deletions
21
src/main/java/com/uspray/uspray/external/client/oauth2/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,21 @@ | ||
package com.uspray.uspray.external.client.oauth2; | ||
|
||
import com.uspray.uspray.Enums.Authority; | ||
import java.util.Collection; | ||
import java.util.Map; | ||
import lombok.Getter; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.oauth2.core.user.DefaultOAuth2User; | ||
|
||
@Getter | ||
public class CustomOAuth2User extends DefaultOAuth2User { | ||
private final Authority authority; | ||
|
||
public CustomOAuth2User( | ||
Collection<? extends GrantedAuthority> authorities, | ||
Map<String, Object> attributes, String nameAttributeKey, | ||
Authority authority) { | ||
super(authorities, attributes, nameAttributeKey); | ||
this.authority = authority; | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
src/main/java/com/uspray/uspray/external/client/oauth2/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,100 @@ | ||
package com.uspray.uspray.external.client.oauth2; | ||
|
||
import com.uspray.uspray.domain.Member; | ||
import com.uspray.uspray.infrastructure.MemberRepository; | ||
import java.util.Collections; | ||
import lombok.RequiredArgsConstructor; | ||
import org.apache.commons.lang3.RandomStringUtils; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.authority.SimpleGrantedAuthority; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
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; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> { | ||
|
||
private final MemberRepository memberRepository; | ||
|
||
/** | ||
* DefaultOAuth2UserService 객체를 생성하여, loadUser(userRequest)를 통해 DefaultOAuth2User 객체를 생성 후 반환 | ||
* DefaultOAuth2UserService의 loadUser()는 소셜 로그인 API의 사용자 정보 제공 URI로 요청을 보내서 | ||
* 사용자 정보를 얻은 후, 이를 통해 DefaultOAuth2User 객체를 생성 후 반환한다. | ||
* 결과적으로, OAuth2User는 OAuth 서비스에서 가져온 유저 정보를 담고 있는 유저 | ||
*/ | ||
@Override | ||
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { | ||
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService(); | ||
OAuth2User oAuth2User = delegate.loadUser(userRequest); // OAuth2 정보를 가져옵니다. | ||
|
||
//현재 로그인 진행 중인 서비스를 구분하는 코드 (구글 or 네이버 or 카카오 ...) | ||
String registrationId = userRequest.getClientRegistration().getRegistrationId(); | ||
//OAuth2 로그인 진행 시 키가되는 필드 값, Primary Key와 같은 의미 | ||
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails() | ||
.getUserInfoEndpoint().getUserNameAttributeName(); | ||
|
||
//OAuth2UserService를 통해 가져온 OAuth2User의 attribute를 담을 클래스 | ||
// 소셜 로그인에서 API가 제공하는 userInfo의 Json 값(유저 정보들) | ||
OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNameAttributeName, | ||
oAuth2User.getAttributes()); | ||
|
||
Member member = getMember(attributes); | ||
|
||
return new CustomOAuth2User( | ||
Collections.singleton(new SimpleGrantedAuthority(member.getAuthority().name())), | ||
oAuth2User.getAttributes(), | ||
attributes.getNameAttributeKey(), | ||
member.getAuthority() | ||
); | ||
} | ||
|
||
private Member getMember(OAuthAttributes attributes) { | ||
Member findMember = memberRepository.findBySocialId( | ||
attributes.getOAuth2UserInfo().getId()).orElse(null); | ||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||
|
||
if (authentication != null) { //소셜 로그인 연동 | ||
return saveMember(attributes, authentication.getName()); | ||
} | ||
|
||
if (findMember == null) { | ||
return saveMember(attributes); | ||
} | ||
|
||
return findMember; | ||
} | ||
|
||
/** | ||
* 이미 존재하는 회원이라면 이름과 프로필이미지를 업데이트해줍니다. | ||
* 처음 가입하는 회원이라면 Member 테이블을 생성합니다. (소셜 회원가입) | ||
**/ | ||
private Member saveMember(OAuthAttributes attributes, String userId) { | ||
//기존 유저와 아이디가 같으면 같은 유저임 | ||
// update는 기존 유저의 소셜 ID 컬럼에 값을 추가하는 것 정도만 있으면 될듯 | ||
Member member = memberRepository.getMemberByUserId(userId); | ||
member.changeSocialId(attributes.getOAuth2UserInfo().getId()); | ||
return memberRepository.save(member); | ||
} | ||
|
||
private Member saveMember(OAuthAttributes attributes) { | ||
//기존 유저와 아이디가 같으면 같은 유저임 | ||
// update는 기존 유저의 소셜 ID 컬럼에 값을 추가하는 것 정도만 있으면 될듯 | ||
Member member = attributes.toEntity(attributes.getOAuth2UserInfo(), generateRandomId()); | ||
return memberRepository.save(member); | ||
} | ||
|
||
private String generateRandomId() { | ||
while (true) { | ||
String randomId = RandomStringUtils.random(15, true, true); | ||
if (!memberRepository.existsByUserId(randomId)) { | ||
return randomId; | ||
} | ||
} | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
src/main/java/com/uspray/uspray/external/client/oauth2/OAuth2LoginFailureHandler.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,23 @@ | ||
package com.uspray.uspray.external.client.oauth2; | ||
|
||
import java.io.IOException; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.web.authentication.AuthenticationFailureHandler; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Slf4j | ||
@Component | ||
public class OAuth2LoginFailureHandler implements AuthenticationFailureHandler { | ||
|
||
@Override | ||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, | ||
AuthenticationException exception) throws IOException, ServletException { | ||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST); | ||
response.getWriter().write("소셜 로그인이 실패하였습니다."); | ||
log.error("소셜 로그인에 실패했습니다. 에러메세지 : {}", exception.getMessage()); | ||
} | ||
} |
Oops, something went wrong.