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
refactor: 카카오 로그인 피드백 반영 #126
refactor: 카카오 로그인 피드백 반영 #126
Conversation
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.
안녕하세요 시카!
제가 컨벤션 안 지킨 부분을 다 고쳐주셨네요. 너무 감사합니다😊
사소한 피드백 남겼어요 확인해주세요. 대부분 제 의견이라, 선택적으로 반영해주세요
@@ -25,30 +25,26 @@ | |||
@EqualsAndHashCode(of = "id") | |||
@Getter | |||
public class Certification { | |||
@Id | |||
@With(value = AccessLevel.PACKAGE) | |||
@Id @With(value = AccessLevel.PACKAGE) |
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.
고맙습니다😊
@@ -13,6 +13,7 @@ | |||
MEMBER_NOT_FOUND(400, "Member-001"), | |||
MEMBER_DUPLICATE(400, "Member-002"), | |||
MEMBER_ID_INVALID(400, "Member-003"), | |||
MEMBER_NOT_FOUND_WITH_KAKAO_ID(400, "Member-004"), |
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.
처음에 제안할 때는 001을 NOT_FOUND라고 생각했는데, 어떻게 생각하시나요?
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.
직접 이야기를 들어보니 Code 의미를 알기 쉽게하기라는 취지는 좋네요 :)
다만 다른 팀원들과 조금 더 얘기해 볼 필요가 있을 것 같아요.
@@ -28,7 +28,7 @@ public JdbcCustomConversions jdbcCustomConversions() { | |||
Arrays.asList(new Converter<Clob, String>() { | |||
@Nullable | |||
@Override | |||
public String convert(Clob clob) { | |||
public String convert(final Clob clob) { |
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.
final 귀신...👏
registry.addInterceptor(bearerAuthInterceptor) | ||
.addPathPatterns("/**"); | ||
final List<String> pathPatterns = Arrays.asList( | ||
"/api/certifications/**", "/api/members/**", "/api/missions/**", |
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.
exclude가 안되는게 아쉽네요😂
try { | ||
final MemberResponse memberResponse = memberService.findByKakaoId(kakaoUserResponse.getId()); | ||
|
||
return JwtTokenResponse.of(jwtTokenProvider.createToken(memberResponse.getKakaoId().toString()), false); |
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.
true, false의 의미를 파악하기 어렵네요. 의미있는 상수로 분리하면 어떨까요?
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.
private static final boolean NOT_CREATED = false;
private static final boolean CREATED = true;
의미 파악이 쉽도록 수정 완료 :)
@Service | ||
@Transactional | ||
public class LoginService { | ||
private final KakaoAPIService kakaoAPIService; |
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.
LoginApiService를 사용하지 않고 KakaoApiService를 사용하는 이유가 있나요?
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.
오 👍
LoginAPIService가 나중에 생겨서 빼먹었나봐요 수정했습니다
import com.woowacourse.pelotonbackend.support.dto.JwtTokenResponse; | ||
import reactor.core.publisher.Mono; | ||
|
||
@Component | ||
@Transactional | ||
public class KakaoAPIService implements LoginService { | ||
public class KakaoAPIService implements LoginAPIService<KakaoTokenResponse, KakaoUserResponse> { |
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.
Generic 사용 좋네요😊
if (Objects.isNull(attribute)) { | ||
return Member.builder().build(); | ||
return MemberResponse.builder().build(); |
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.
예외를 여기서 반환해도 되는데 굳이 빈 객체를 넘기는 이유가 있나요? 이 부분도 리뷰로 남겼었는데 어떻게 생각하는지 적어주시면 좋을 것 같아요.
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.
같이 이야기 한대로 AssertionError
를 던지도록 수정했어요.
추가로 GlobalExceptionHandler에
@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> UnexpectedException(final Exception exception) {
log.error("Unexpected Exception ! ", exception);
final ErrorResponse errorResponse = ErrorResponse.of(
ErrorCode.UNEXPECTED.getStatus(),
ErrorCode.UNEXPECTED.getCode(),
exception.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.valueOf(ErrorCode.UNEXPECTED.getStatus()));
}
예기치 못한 에러를 처리하도록 추가했습니다.
|
||
return memberService.findByKakaoId(kakaoId).orElseThrow(() -> new MemberNotFoundException(kakaoId)); | ||
final long kakaoId = Long.parseLong(attribute); |
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.
지금 반영할 필요는 없지만 MemberResponse보단 차라리, 회원을 분리하는 것도 좋은 방법 같아요.
현재는 Member가 회원이면서 권한을 직접 갖는 객체지만 예를 들어 MemberAuthority와 Member를 분리한다면 MemberResponse대신 MemberAuthority라는 도메인을 가질 수 있을 것 같네요.
MemberAuthority는 Id와 권한 관련 필드만 존재하고, 실제 회원 정보 및 기능은 Member에 존재하는 형태로 생각해봤습니다.
@@ -62,10 +62,13 @@ | |||
} | |||
|
|||
@ExceptionHandler(RaceNotFoundException.class) |
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.
이 메소드가 여기 있을 이유가 있나요? GlobalExceptionHandler에서 처리하지 않나요?
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.
살짝 수정할 사항 남겼습니다 :)
final String bearer = authExtractor.extract(request); | ||
final String kakaoId = jwtTokenProvider.getSubject(bearer); | ||
request.setAttribute("loginMemberKakaoId", kakaoId); | ||
|
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.
개인적으로 이부분을 메서드로 빼서 의미를 분명히 해주면 좋을 것 같아요.
exclude 패턴이 아니라면 -> 검증하고, attribute를 set 해준다는 느낌으로요.
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.
preHandle이라는 메서드 명이 의미가 애매모호하긴 하네요.
그래도 BearerAuthInterceptor가 preHandle을 한다고 생각하면 조금 괜찮을 것 같아요!
import reactor.core.publisher.Mono; | ||
|
||
@ExtendWith(MockitoExtension.class) | ||
@AutoConfigureWebTestClient |
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.
테스트에서 webclient를 사용하지 않아서 이 어노테이션은 필요없겠네요.
private LoginService loginService; | ||
|
||
@Mock | ||
private KakaoAPIService kakaoAPIService; |
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.
이 부분도 마찬가지로 LoginAPIService가 되는 건 어떨까요?
@Test | ||
void createJwtTokenUrlTest() { | ||
when(kakaoAPIService.createTokenUrl(any(JwtTokenResponse.class))).thenReturn(URL); | ||
when(kakaoAPIService.fetchOAuthToken(anyString())).thenReturn(Mono.just(createMockKakaoTokenResponse())); |
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.
anyString
보다는 CODE_VALUE
로 정확한 값을 넣어주는 게 좋을 것 같아요.
EqualsAndHashcode
가 구현되지 않은 클래스들이야 어쩔 수 없이 any
를 사용한다고 해도, 비교가 가능한 객체들에 대해서는 정확한 비교를 해주는 게 좋다고 생각합니다.
@Test | ||
public void retrieveNewMemberTest() { | ||
void findByKakaoIdTest2() { |
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.
test2라는 메서드 네이밍보다는 예외에 관련된 네이밍을 하는게 좋지 않을까요?
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.
저는 개인적으로 DisplayName으로 명시만 해주면 괜찮다고 생각해요
userResponse = new MockResponse() | ||
.addHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) | ||
.setResponseCode(HttpStatus.OK.value()) | ||
.setBody(objectMapper.writeValueAsString(createMockKakaoUserResponse())); |
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.
byte는 어떨까요?
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.
안됩니다
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.
고생하셨습니다 :)
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.
tr
39fc8c9
to
0ef6836
Compare
피드백 반영 했으니 확인해주세요 :)