-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/#14 social login kakao #15
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.with.picme.common; | ||
|
||
public enum SocialType { | ||
kakao | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.with.picme.config.kakao; | ||
|
||
|
||
import com.with.picme.dto.auth.kakao.KakaoUserResponseDto; | ||
import org.springframework.cloud.openfeign.FeignClient; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestHeader; | ||
|
||
@FeignClient(name = "kakaoAuth", url = "https://kapi.kakao.com") | ||
public interface KakaoAuth { | ||
|
||
@GetMapping("/v2/user/me") | ||
KakaoUserResponseDto getProfileInfo(@RequestHeader("Authorization") String accessToken); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.with.picme.config.kakao; | ||
|
||
import com.with.picme.common.message.ErrorMessage; | ||
import com.with.picme.dto.auth.kakao.KakaoUser; | ||
import com.with.picme.dto.auth.kakao.KakaoUserResponseDto; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.persistence.EntityNotFoundException; | ||
|
||
import static com.with.picme.common.message.ErrorMessage.*; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class KakaoAuthImpl implements KakaoAuth { | ||
private final KakaoAuth kakaoAuth; | ||
|
||
@Override | ||
public KakaoUserResponseDto getProfileInfo(String accessToken) { | ||
try { | ||
KakaoUserResponseDto kakaoProfile = kakaoAuth.getProfileInfo(accessToken); | ||
return kakaoProfile; | ||
} catch (Exception e) { | ||
throw new EntityNotFoundException(ErrorMessage.NOT_FOUND_SOCIAL_TOKEN.getMessage()); | ||
} | ||
} | ||
|
||
public KakaoUser getKakaoUser(String accessToken){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거는 어디서 쓰는걸까요? interface를 만들었으면 Override해야 의미가 있다고 생각합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. authService -> kakao->check에 쓰입니다! |
||
KakaoUserResponseDto user = this.getProfileInfo(accessToken); | ||
if(!checkSocialUser(user)){ | ||
throw new IllegalArgumentException(NO_SOCIAL_USER.getMessage()); | ||
}; | ||
KakaoUser kakaoUser = checkSocialUserHaveEmail(user); | ||
return kakaoUser; | ||
} | ||
|
||
private boolean checkSocialUser(KakaoUserResponseDto kakaoUser){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 리턴값을 사용하지 않으니까 void는 어떤가요?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아주 좋습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. chckSocialUser는 Check한다는 역할만 부여하고(true / false 반환) 위에 getKakaoUser에서 throw하는게 더 바람직할 거 같아요! 메소드의 이름과 역할이 명확한게 중요하다 생각해서 남깁니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! 감사합니다! |
||
if (kakaoUser.id() == null){ | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
private KakaoUser checkSocialUserHaveEmail(KakaoUserResponseDto kakaoUserResponseDto){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. email 등록되어있음 갖다 쓰고, 없으면 안쓰는 형식일까요?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵맞습니당! |
||
String email = ""; | ||
if (kakaoUserResponseDto.kakao_account().email() != null) { | ||
email = kakaoUserResponseDto.kakao_account().email(); | ||
} | ||
return KakaoUser.of(kakaoUserResponseDto.id(), email); | ||
} | ||
Comment on lines
+44
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 대왕꼼꼼!!! 👍👍👍👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 온냐가 노드로 구현한거 그대로 로직 작성한거얌~ |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
package com.with.picme.controller; | ||
|
||
import com.with.picme.common.ApiResponse; | ||
import com.with.picme.dto.auth.AuthSignInRequestDto; | ||
import com.with.picme.dto.auth.AuthSignInResponseDto; | ||
import com.with.picme.dto.auth.AuthSignUpRequestDto; | ||
import com.with.picme.dto.auth.AuthSignUpResponseDto; | ||
import com.with.picme.dto.auth.*; | ||
import com.with.picme.dto.auth.kakao.KakaoUser; | ||
import com.with.picme.entity.User; | ||
import com.with.picme.repository.AuthenticationProviderRepository; | ||
import com.with.picme.service.AuthServiceImpl; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
|
@@ -13,14 +13,16 @@ | |
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import javax.validation.Valid; | ||
import static com.with.picme.common.message.ResponseMessage.SUCCESS_SIGN_IN; | ||
import static com.with.picme.common.message.ResponseMessage.SUCCESS_SIGN_UP; | ||
|
||
|
||
import static com.with.picme.common.message.ResponseMessage.*; | ||
|
||
@RestController | ||
@RequestMapping("/auth") | ||
@RequiredArgsConstructor | ||
public class AuthController { | ||
private final AuthServiceImpl authService; | ||
private final AuthenticationProviderRepository authenticationProviderRepository; | ||
|
||
@PostMapping("") | ||
public ResponseEntity<ApiResponse> createUser(@RequestBody @Valid AuthSignUpRequestDto request) { | ||
|
@@ -33,4 +35,10 @@ public ResponseEntity<ApiResponse> signInUser(@RequestBody AuthSignInRequestDto | |
AuthSignInResponseDto response = authService.signInUser(request); | ||
return ResponseEntity.ok(ApiResponse.success(SUCCESS_SIGN_IN.getMessage(), response)); | ||
} | ||
|
||
@PostMapping("/kakao/check") | ||
public ResponseEntity<ApiResponse> findSocialUser(@RequestBody AuthSocialCheckRequestDto request) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 말씀하신대로 해당 로직 다 service로 넘기는게 맞다고 생각해요. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵알겠습니당! |
||
AuthSocialCheckResponseDto response = authService.findSocialUser(request); | ||
return ResponseEntity.ok(ApiResponse.success(CHECK_KAKAO_USER_SUCCESS.getMessage(),response)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.with.picme.dto.auth; | ||
|
||
|
||
import javax.validation.constraints.NotBlank; | ||
|
||
|
||
public record AuthSocialCheckRequestDto( | ||
@NotBlank(message="필요한 값이 없습니다") | ||
String socialType, | ||
|
||
@NotBlank(message = "필요한 값이 없습니다.") | ||
String token | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.with.picme.dto.auth; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record AuthSocialCheckResponseDto ( | ||
Long uid, | ||
String email, | ||
boolean isUser | ||
){ | ||
public static AuthSocialCheckResponseDto of(Long uid, String email, boolean isUser){ | ||
return AuthSocialCheckResponseDto | ||
.builder() | ||
.uid(uid) | ||
.email(email) | ||
.isUser(isUser) | ||
.build(); | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.with.picme.dto.auth.kakao; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record KakaoAccount( | ||
String email | ||
) { | ||
public static KakaoAccount of(String email){ | ||
return KakaoAccount | ||
.builder() | ||
.email(email) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.with.picme.dto.auth.kakao; | ||
|
||
|
||
import com.with.picme.entity.ProviderType; | ||
import lombok.Builder; | ||
|
||
@Builder | ||
public record KakaoUser( | ||
Long userId, | ||
String email, | ||
ProviderType providerType | ||
) { | ||
public static KakaoUser of(Long userId, String email){ | ||
return KakaoUser | ||
.builder() | ||
.userId(userId) | ||
.email(email) | ||
.providerType(ProviderType.kakao) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.with.picme.dto.auth.kakao; | ||
|
||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record KakaoUserResponseDto( | ||
Long id, | ||
KakaoAccount kakao_account | ||
GaHee99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) { | ||
public static KakaoUserResponseDto of(Long id, KakaoAccount kakaoAccount) { | ||
return KakaoUserResponseDto | ||
.builder() | ||
.id(id) | ||
.kakao_account(kakaoAccount) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
package com.with.picme.entity; | ||
|
||
import javax.persistence.EnumType; | ||
import javax.persistence.Enumerated; | ||
|
||
public enum ProviderType { | ||
@Enumerated(EnumType.STRING) | ||
kakao, naver, google | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.with.picme.repository; | ||
|
||
import com.with.picme.entity.AuthenticationProvider; | ||
import com.with.picme.entity.ProviderType; | ||
import org.springframework.data.jpa.repository.EntityGraph; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
|
||
import java.util.Optional; | ||
|
||
public interface AuthenticationProviderRepository extends JpaRepository<AuthenticationProvider, Long> { | ||
@EntityGraph(attributePaths = "user") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 알아가요! 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 감사해요!! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 어떤 어노테이션인지 잘 몰라서 간략하게 설명 부탁드려도 될까용?!~새로 배운다 야호! |
||
Optional<AuthenticationProvider> findByIdAndProvider(Long id, ProviderType providerType); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,15 @@ | ||
package com.with.picme.service; | ||
|
||
import com.with.picme.dto.auth.AuthSignInRequestDto; | ||
import com.with.picme.dto.auth.AuthSignInResponseDto; | ||
import com.with.picme.dto.auth.AuthSignUpRequestDto; | ||
import com.with.picme.dto.auth.AuthSignUpResponseDto; | ||
import com.with.picme.dto.auth.*; | ||
import com.with.picme.dto.auth.kakao.KakaoUser; | ||
import com.with.picme.entity.AuthenticationProvider; | ||
import com.with.picme.entity.User; | ||
|
||
import java.util.Optional; | ||
|
||
public interface AuthService { | ||
|
||
AuthSignUpResponseDto createUser(AuthSignUpRequestDto request); | ||
AuthSignInResponseDto signInUser(AuthSignInRequestDto request); | ||
AuthSocialCheckResponseDto findSocialUser(AuthSocialCheckRequestDto request); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
package com.with.picme.service; | ||
|
||
import com.with.picme.common.SocialType; | ||
import com.with.picme.common.message.ErrorMessage; | ||
import com.with.picme.config.kakao.KakaoAuthImpl; | ||
import com.with.picme.config.SaltEncrypt; | ||
import com.with.picme.config.jwt.JwtTokenProvider; | ||
import com.with.picme.config.jwt.UserAuthentication; | ||
import com.with.picme.dto.auth.AuthSignInRequestDto; | ||
import com.with.picme.dto.auth.AuthSignInResponseDto; | ||
import com.with.picme.dto.auth.AuthSignUpRequestDto; | ||
import com.with.picme.dto.auth.AuthSignUpResponseDto; | ||
import com.with.picme.dto.auth.*; | ||
import com.with.picme.dto.auth.kakao.KakaoUser; | ||
import com.with.picme.entity.AuthenticationProvider; | ||
import com.with.picme.entity.User; | ||
import com.with.picme.repository.AuthenticationProviderRepository; | ||
import com.with.picme.repository.UserRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.security.core.Authentication; | ||
|
@@ -16,6 +19,8 @@ | |
|
||
import javax.persistence.EntityNotFoundException; | ||
|
||
import java.util.Optional; | ||
|
||
import static com.with.picme.common.message.ErrorMessage.*; | ||
|
||
@RequiredArgsConstructor | ||
|
@@ -25,7 +30,8 @@ public class AuthServiceImpl implements AuthService { | |
private final UserRepository userRepository; | ||
private final SaltEncrypt saltEncrypt; | ||
private final JwtTokenProvider tokenProvider; | ||
|
||
private final KakaoAuthImpl kakaoAuthImpl; | ||
private final AuthenticationProviderRepository authenticationProviderRepository; | ||
@Override | ||
public AuthSignUpResponseDto createUser(AuthSignUpRequestDto request) { | ||
if (validateEmail(request.email())) | ||
|
@@ -66,6 +72,28 @@ public AuthSignInResponseDto signInUser(AuthSignInRequestDto request) { | |
return AuthSignInResponseDto.of(user, accessToken); | ||
} | ||
|
||
|
||
@Override | ||
public AuthSocialCheckResponseDto findSocialUser(AuthSocialCheckRequestDto request) { | ||
if (!request.socialType().equals(SocialType.kakao.toString())) { //토큰 타입 확인 | ||
throw new IllegalArgumentException(NO_SOCIAL_TYPE.getMessage()); | ||
} | ||
KakaoUser kakaoUser = kakaoAuthImpl.getKakaoUser("Bearer " + request.token()); //카카오 계정 확인 | ||
|
||
Optional<AuthenticationProvider> authenticationProvider = authenticationProviderRepository.findByIdAndProvider(kakaoUser.userId(), kakaoUser.providerType()); | ||
|
||
// 카카오 계정으로 우리 서비스에 회원가입 함 | ||
if(authenticationProvider.isPresent()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 말씀드렸듯이 위에 getUser와 findByKey 합치는게 좋을거 같아요! 이거 차이가 true, false밖에 없는데, isPresent일때 true DTO 반환하고 아닐때는 false DTO 반환하면 될거 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵!!! 감사합니다! |
||
Long userId = authenticationProvider.get().getUser().getId(); | ||
//유저 테이블에서 찾기 | ||
userRepository.findById(userId) | ||
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.CANT_GET_USERINFO.getMessage())); | ||
return AuthSocialCheckResponseDto.of(kakaoUser.userId(),kakaoUser.email(),true); | ||
} | ||
// 카카오 계정은 확인, 우리 서비스에는 회원가입 안됨 | ||
return AuthSocialCheckResponseDto.of(kakaoUser.userId(),kakaoUser.email(),false); | ||
} | ||
|
||
private User checkPassword(String email, String password) { | ||
User user = userRepository.findByEmail(email); | ||
if (saltEncrypt.isMatch(password, user.getPassword())) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기
url
을 yml에 따로 빼주면 좋을 거 같아요!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵!