Skip to content

Commit

Permalink
로그인 기능 수정 (#89)
Browse files Browse the repository at this point in the history
* feat: 카카오 로그인 요청 DTO 정의(#88)

* feat: 카카오 로그인 요청 로직 수정(#88)

카카오 로그인 API의 bad request 응답에 대한 예외 처리 추가

* feat: 카카오 로그인 비즈니스 로직 수정(#88)

request dto를 통해 로그인 수행하도록 로직 변경

* feat: 카카오 로그인 API 추가(#88)

- 인가 코드를 프론트에서 넘겨받는 플로우로 로그인 로직 재구성
- 새로 API 구현 및 명세
  • Loading branch information
Minjae-An authored Oct 8, 2024
1 parent 38cc754 commit 5bda7f2
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,14 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.example.tokpik_be.exception.GeneralException;
import org.example.tokpik_be.exception.LoginException;
import org.example.tokpik_be.login.dto.request.AccessTokenRefreshRequest;
import org.example.tokpik_be.login.dto.request.LoginByKakaoRequest;
import org.example.tokpik_be.login.dto.response.AccessTokenRefreshResponse;
import org.example.tokpik_be.login.dto.response.LoginResponse;
import org.example.tokpik_be.login.service.LoginCommandService;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "Login API", description = "로그인 관련 API")
Expand All @@ -26,16 +22,13 @@ public class LoginController {

private final LoginCommandService loginCommandService;

@GetMapping("/oauth/kakao")
@Operation(summary = "카카오 소셜 로그인", description = "카카오 인카 코드 바탕 소셜 로그인 수행")
@ApiResponse(responseCode = "200", description = "카카오 소셜 로그인 성공")
@PostMapping("/login/kakao")
public ResponseEntity<LoginResponse> kakaoLogin(
@RequestParam("code") String code,
@RequestParam(name = "error", required = false) String error) {
@RequestBody @Valid LoginByKakaoRequest request) {

if (StringUtils.hasText(error)) {
throw new GeneralException(LoginException.LOGIN_FAIL);
}

LoginResponse response = loginCommandService.kakaoLogin(code);
LoginResponse response = loginCommandService.kakaoLogin(request);

return ResponseEntity.ok().body(response);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.example.tokpik_be.login.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

public record LoginByKakaoRequest(
@Schema(type = "string", description = "카카오 서버로부터 받은 인가 코드", example = "code")
@NotBlank(message = "인가 코드는 필수 값")
String code
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,29 @@
import java.util.Base64;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.example.tokpik_be.exception.GeneralException;
import org.example.tokpik_be.exception.LoginException;
import org.example.tokpik_be.login.dto.response.KakaoUserResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Component
@RequiredArgsConstructor
public class KakaoApiClient {

private final ObjectMapper objectMapper;
@Value("${KAKAO_API_CLIENT_ID}")
private String clientId;

@Value("${KAKAO_LOGIN_REDIRECT_URL}")
private String redirectUrl;
private final ObjectMapper objectMapper;

public KakaoUserResponse requestKakaoUser(String code) {
WebClient webClient = WebClient.builder()
Expand All @@ -37,14 +40,20 @@ public KakaoUserResponse requestKakaoUser(String code) {
loginRequest.add("redirect_uri", redirectUrl);
loginRequest.add("code", code);

Map<String, String> response = webClient.post()
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.body(BodyInserters.fromFormData(loginRequest))
.retrieve()
.bodyToMono(Map.class)
.block();
try {
Map<String, String> response = webClient.post()
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.body(BodyInserters.fromFormData(loginRequest))
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError,
apiResponse -> Mono.error(new GeneralException(LoginException.LOGIN_FAIL)))
.bodyToMono(Map.class)
.block();

return toKakaoLoginResponse(response);
return toKakaoLoginResponse(response);
} catch (GeneralException e) {
throw e;
}
}

private KakaoUserResponse toKakaoLoginResponse(Map<String, String> response) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.example.tokpik_be.exception.GeneralException;
import org.example.tokpik_be.exception.LoginException;
import org.example.tokpik_be.login.dto.request.AccessTokenRefreshRequest;
import org.example.tokpik_be.login.dto.request.LoginByKakaoRequest;
import org.example.tokpik_be.login.dto.response.AccessTokenRefreshResponse;
import org.example.tokpik_be.login.dto.response.KakaoUserResponse;
import org.example.tokpik_be.login.dto.response.LoginResponse;
Expand All @@ -25,9 +26,9 @@ public class LoginCommandService {
private final KakaoApiClient kakaoApiClient;
private final JwtUtil jwtUtil;

public LoginResponse kakaoLogin(String code) {
public LoginResponse kakaoLogin(LoginByKakaoRequest request) {

KakaoUserResponse kakaoUserResponse = kakaoApiClient.requestKakaoUser(code);
KakaoUserResponse kakaoUserResponse = kakaoApiClient.requestKakaoUser(request.code());
String email = kakaoUserResponse.email();

if (userQueryService.notExistByEmail(email)) {
Expand Down

0 comments on commit 5bda7f2

Please sign in to comment.