Skip to content
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

[Feature] - 인증과정 예외처리 #84

Merged
merged 6 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package woowacourse.touroot.authentication.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -8,14 +13,26 @@
import org.springframework.web.bind.annotation.RestController;
import woowacourse.touroot.authentication.dto.LoginResponse;
import woowacourse.touroot.authentication.service.LoginService;
import woowacourse.touroot.global.exception.dto.ExceptionResponse;

@Tag(name = "로그인")
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/login")
public class LoginController {

private final LoginService loginService;

@Operation(
summary = "카카오 로그인",
responses = {
@ApiResponse(
responseCode = "400",
description = "유효하지 않은 인가 코드로 로그인 요청을 했을 때",
content = @Content(schema = @Schema(implementation = ExceptionResponse.class))
)
}
)
@GetMapping("/oauth/kakao")
public ResponseEntity<LoginResponse> login(@RequestParam(name = "code") String authorizationCode) {
return ResponseEntity.ok()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
package woowacourse.touroot.authentication.dto;

public record LoginResponse(String accessToken) {
import io.swagger.v3.oas.annotations.media.Schema;
import woowacourse.touroot.member.domain.Member;

public record LoginResponse(
@Schema(description = "로그인된 유저의 닉네임") String nickname,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

질문) login이 성공됐다는 응답으로 nickname, prifleImageUrl이 어떤 상황에서 필요한가요? 어디에 쓰이는지 궁금합니당

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제 생각에는 프론트엔드에서 활용할 수 있을 것 같습니다.
따로 사용자 정보 요청 API 호출 없이도 로그인 후에 바로 사용자 정보를 가져갈 수 있지 않을까용?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리건 말이 맞습니다. 여러 서비스에서 로그인 되면 우측 상단에 프로필이미지랑 닉네임 뜨듯이 저희 서비스에서도 사용할 수 있는 맥락을 고려했어요

@Schema(description = "로그인된 유저의 프로필 이미지 경로") String profileImageUrl,
@Schema(description = "인가에 필요한 accessToken") String accessToken) {

public static LoginResponse of(Member member, String accessToken) {
return new LoginResponse(member.getNickname(), member.getProfileImageUri(), accessToken);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package woowacourse.touroot.authentication.infrastructure;

import java.io.IOException;
import java.time.Duration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.ClientHttpRequestFactories;
import org.springframework.boot.web.client.ClientHttpRequestFactorySettings;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClient;
import woowacourse.touroot.authentication.dto.KakaoAccessTokenResponse;
import woowacourse.touroot.authentication.dto.OauthUserInformationResponse;
import woowacourse.touroot.global.exception.BadRequestException;
import woowacourse.touroot.global.exception.ClientException;

@Component
public class KakaoOauthClient {
Expand Down Expand Up @@ -55,6 +61,7 @@ public OauthUserInformationResponse requestUserInformation(String authorizationC
.uri(userInformationRequestUri)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + kakaoAccessTokenResponse.accessToken())
.retrieve()
.onStatus(HttpStatusCode::isError, this::handleClientError)
.toEntity(OauthUserInformationResponse.class)
.getBody();
}
Expand All @@ -71,7 +78,15 @@ private KakaoAccessTokenResponse requestAccessToken(String authorizationCode) {
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(params)
.retrieve()
.onStatus(HttpStatusCode::isError, this::handleClientError)
.toEntity(KakaoAccessTokenResponse.class)
.getBody();
}

private void handleClientError(HttpRequest request, ClientHttpResponse response) throws IOException {
if (response.getStatusCode().is4xxClientError()) {
throw new BadRequestException("잘못된 로그인 요청입니다. 인가코드를 확인해주세요");
}
throw new ClientException("외부 서비스의 장애로 카카오로그인을 이용할 수 없습니다");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public LoginResponse login(String code) {
Member member = memberRepository.findByKakaoId(userInformation.socialLoginId())
.orElseGet(() -> signUp(userInformation));

return new LoginResponse(tokenProvider.createToken(member));
return LoginResponse.of(member, tokenProvider.createToken(member));
}

private Member signUp(OauthUserInformationResponse userInformation) {
return memberRepository.save(
new Member(userInformation.socialLoginId(), userInformation.nickname(), userInformation.profileImage())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package woowacourse.touroot.global.exception;

public class ClientException extends RuntimeException {

public ClientException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ public ResponseEntity<ExceptionResponse> handleMethodArgumentNotValidException(
return ResponseEntity.badRequest()
.body(data);
}

@ExceptionHandler(ClientException.class)
public ResponseEntity<ExceptionResponse> handleClientException(ClientException exception) {
log.error("CLIENT_EXCEPTION :: message = {}", exception.getMessage());

ExceptionResponse data = new ExceptionResponse(exception.getMessage());
return ResponseEntity.internalServerError().body(data);
}
}
Loading