From 160b275bfe22fcd42af687facea0b5880e4d7ea4 Mon Sep 17 00:00:00 2001 From: gitchan Date: Mon, 18 Mar 2024 17:44:24 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20oauth=20t?= =?UTF-8?q?oken=20=EB=B0=9B=EC=95=84=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/api/KakaoMemberApiController.java | 7 ++ .../auth/application/KakaoMemberService.java | 20 ++++-- .../server/auth/client/KakaoOAuthClient.java | 65 +++++++++++++++++++ .../client/response/KakaoOAuthResponse.java | 30 +++++++++ .../server/client/ApiOcrDownloadClient.java | 2 +- server/src/test/resources/application.yml | 1 + 6 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 server/src/main/java/sunflower/server/auth/client/KakaoOAuthClient.java create mode 100644 server/src/main/java/sunflower/server/auth/client/response/KakaoOAuthResponse.java diff --git a/server/src/main/java/sunflower/server/auth/api/KakaoMemberApiController.java b/server/src/main/java/sunflower/server/auth/api/KakaoMemberApiController.java index b6522d9..aba8498 100644 --- a/server/src/main/java/sunflower/server/auth/api/KakaoMemberApiController.java +++ b/server/src/main/java/sunflower/server/auth/api/KakaoMemberApiController.java @@ -4,6 +4,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import sunflower.server.application.SessionService; import sunflower.server.auth.application.KakaoMemberService; @@ -22,4 +23,10 @@ public ResponseEntity login() { .header("Location", uri) .build(); } + + @GetMapping("/login/kakao/session") + public ResponseEntity authorize(@RequestParam("code") String code) { + kakaoMemberService.login(code); + return null; + } } diff --git a/server/src/main/java/sunflower/server/auth/application/KakaoMemberService.java b/server/src/main/java/sunflower/server/auth/application/KakaoMemberService.java index d48143a..0510071 100644 --- a/server/src/main/java/sunflower/server/auth/application/KakaoMemberService.java +++ b/server/src/main/java/sunflower/server/auth/application/KakaoMemberService.java @@ -2,25 +2,37 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import sunflower.server.auth.client.KakaoOAuthClient; @Service public class KakaoMemberService { - private String redirectURI; - private String restApiKey; - private String authCodeURI; + private final String redirectURI; + private final String restApiKey; + private final String authCodeURI; + private final String authTokenURI; + private final KakaoOAuthClient kakaoOAuthClient; public KakaoMemberService( @Value("${oauth.kakao.rest-api-key}") String restApiKey, @Value("${oauth.kakao.redirect-uri}") String redirectURI, - @Value("${oauth.kakao.auth-code-uri}") String authCodeURI + @Value("${oauth.kakao.auth-code-uri}") String authCodeURI, + @Value("${oauth.kakao.token-uri}") String authTokenURI, + final KakaoOAuthClient kakaoOAuthClient ) { this.redirectURI = redirectURI; this.restApiKey = restApiKey; this.authCodeURI = authCodeURI; + this.authTokenURI = authTokenURI; + this.kakaoOAuthClient = kakaoOAuthClient; } public String loginURI() { return String.format(authCodeURI, restApiKey, redirectURI); } + + public String login(final String code) { + kakaoOAuthClient.login(authTokenURI, restApiKey, redirectURI, code); + return null; + } } diff --git a/server/src/main/java/sunflower/server/auth/client/KakaoOAuthClient.java b/server/src/main/java/sunflower/server/auth/client/KakaoOAuthClient.java new file mode 100644 index 0000000..f817bf4 --- /dev/null +++ b/server/src/main/java/sunflower/server/auth/client/KakaoOAuthClient.java @@ -0,0 +1,65 @@ +package sunflower.server.auth.client; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import sunflower.server.auth.client.response.KakaoOAuthResponse; + +import java.util.Map; + +@Slf4j +@Component +public class KakaoOAuthClient { + + private final ObjectMapper objectMapper = new ObjectMapper(); + private static final String GRANT_TYPE = "authorization_code"; + private final RestTemplate restTemplate; + + public KakaoOAuthClient(final RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public void login(final String authTokenURI, final String restApiKey, final String redirectURI, final String code) { + final String requestURI = authTokenURI; + HttpHeaders requestHeader = createRequestHeader(); + final MultiValueMap requestBody = createRequestBody(restApiKey, redirectURI, code); + final HttpEntity> requestEntity = new HttpEntity<>(requestBody, requestHeader); + + log.info("Request URI: {}", requestURI); + log.info("Request Headers: {}", requestHeader); + log.info("Request Parameters: {}", requestBody); + + final KakaoOAuthResponse response = restTemplate.postForObject(requestURI, requestEntity, KakaoOAuthResponse.class); + } + + private MultiValueMap createRequestBody(final String restApiKey, final String redirectURI, final String code) { + MultiValueMap requestBody = new LinkedMultiValueMap<>(); + + requestBody.add("grant_type", GRANT_TYPE); + requestBody.add("client_id", restApiKey); + requestBody.add("redirect_uri", redirectURI); + requestBody.add("code", code); + + return requestBody; + } + + private String convertToJson(final Map body) { + try { + return objectMapper.writeValueAsString(body); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + private HttpHeaders createRequestHeader() { + HttpHeaders requestHeader = new HttpHeaders(); + requestHeader.set("Content-Type", "application/x-www-form-urlencoded"); + return requestHeader; + } +} diff --git a/server/src/main/java/sunflower/server/auth/client/response/KakaoOAuthResponse.java b/server/src/main/java/sunflower/server/auth/client/response/KakaoOAuthResponse.java new file mode 100644 index 0000000..f7c4362 --- /dev/null +++ b/server/src/main/java/sunflower/server/auth/client/response/KakaoOAuthResponse.java @@ -0,0 +1,30 @@ +package sunflower.server.auth.client.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@ToString +@Getter +@NoArgsConstructor +public class KakaoOAuthResponse { + + @JsonProperty("access_token") + private String accessToken; + + @JsonProperty("token_type") + private String tokenType; + + @JsonProperty("refresh_token") + private String refreshToken; + + @JsonProperty("expires_in") + private String expiresIn; + + @JsonProperty("refresh_token_expires_in") + private String refreshTokenExpiresIn; + + @JsonProperty("scope") + private String scope; +} diff --git a/server/src/main/java/sunflower/server/client/ApiOcrDownloadClient.java b/server/src/main/java/sunflower/server/client/ApiOcrDownloadClient.java index 0f62891..86f7874 100644 --- a/server/src/main/java/sunflower/server/client/ApiOcrDownloadClient.java +++ b/server/src/main/java/sunflower/server/client/ApiOcrDownloadClient.java @@ -25,7 +25,7 @@ public ApiOcrDownloadClient( @Value("${ocr.download-uri}") String appURI, @Value("${ocr.app-id}") String appId, @Value("${ocr.app-key}") String appKey, - RestTemplate restTemplate + final RestTemplate restTemplate ) { this.appURI = appURI; this.appId = appId; diff --git a/server/src/test/resources/application.yml b/server/src/test/resources/application.yml index 954bdf4..954a9b0 100644 --- a/server/src/test/resources/application.yml +++ b/server/src/test/resources/application.yml @@ -13,3 +13,4 @@ oauth: redirect-uri: https://www.sunnybraille.com/login/kakao rest-api-key: rest-api-key auth-code-uri: auth-code-uri + token-uri: token-uri