diff --git a/src/main/java/com/j9/bestmoments/controller/AuthController.java b/src/main/java/com/j9/bestmoments/controller/AuthController.java index 30c5173..2acce34 100644 --- a/src/main/java/com/j9/bestmoments/controller/AuthController.java +++ b/src/main/java/com/j9/bestmoments/controller/AuthController.java @@ -3,6 +3,7 @@ import com.j9.bestmoments.dto.response.LoginDto; import com.j9.bestmoments.dto.response.OAuthUserInfoDto; import com.j9.bestmoments.service.GoogleAuthService; +import com.j9.bestmoments.service.KakaoAuthService; import com.j9.bestmoments.service.OAuthService; import com.j9.bestmoments.domain.Member; import com.j9.bestmoments.service.MemberService; @@ -28,14 +29,16 @@ public class AuthController { private final GoogleAuthService googleAuthService; + private final KakaoAuthService kakaoAuthService; private final MemberService memberService; private final TokenService tokenService; - @GetMapping("/{registrationId}/callback") - @Operation(summary = "OAuth 인증코드로 로그인/회원가입", description = "registrationId: google") + @GetMapping("/{registrationId}/login") + @Operation(summary = "OAuth 인증코드로 로그인/회원가입", description = "registrationId: \"google\" | \"kakao\"") public ResponseEntity login(@PathVariable String registrationId, @RequestParam String code) { OAuthService oAuthService = switch (registrationId) { case "google" -> googleAuthService; + case "kakao" -> kakaoAuthService; default -> throw new OAuth2AuthenticationException("존재하지 않는 OAuth 인증 방식입니다."); }; OAuthUserInfoDto oAuthUserInfo = oAuthService.getUserInfo(code); diff --git a/src/main/java/com/j9/bestmoments/service/GoogleAuthService.java b/src/main/java/com/j9/bestmoments/service/GoogleAuthService.java index ed96f49..1eb95ea 100644 --- a/src/main/java/com/j9/bestmoments/service/GoogleAuthService.java +++ b/src/main/java/com/j9/bestmoments/service/GoogleAuthService.java @@ -18,19 +18,19 @@ @Service public class GoogleAuthService implements OAuthService { - @Value("${spring.security.oauth2.client.registration.google.client-id}") + @Value("${oauth2.google.client-id}") private String clientId; - @Value("${spring.security.oauth2.client.registration.google.client-secret}") + @Value("${oauth2.google.client-secret}") private String clientSecret; - @Value("${spring.security.oauth2.client.registration.google.redirect-uri}") + @Value("${oauth2.google.redirect-uri}") private String redirectUri; - @Value("${spring.security.oauth2.client.registration.google.token-uri}") + @Value("${oauth2.google.token-uri}") private String tokenUri; - @Value("${spring.security.oauth2.client.registration.google.userinfo-uri}") + @Value("${oauth2.google.userinfo-uri}") private String userinfoUrl; @Override diff --git a/src/main/java/com/j9/bestmoments/service/KakaoAuthService.java b/src/main/java/com/j9/bestmoments/service/KakaoAuthService.java new file mode 100644 index 0000000..0250e62 --- /dev/null +++ b/src/main/java/com/j9/bestmoments/service/KakaoAuthService.java @@ -0,0 +1,74 @@ +package com.j9.bestmoments.service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.j9.bestmoments.dto.response.OAuthUserInfoDto; +import java.util.Collections; +import java.util.Map; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +@Service +public class KakaoAuthService implements OAuthService { + + @Value("${oauth2.kakao.client-id}") + private String clientId; + + @Value("${oauth2.kakao.redirect-uri}") + private String redirectUri; + + @Value("${oauth2.kakao.token-uri}") + private String tokenUri; + + @Value("${oauth2.kakao.userinfo-uri}") + private String userinfoUrl; + + @Override + public OAuthUserInfoDto getUserInfo(String code) { + String accessToken = getAccessToken(code); + Map attributes = getUserInfoAttributes(accessToken); + Map kakao_account = (Map) attributes.get("kakao_account"); + Map profile = (Map) kakao_account.get("profile"); + return OAuthUserInfoDto.builder() + .provider("kakao") + .id(attributes.get("id").toString()) + .name(profile.get("nickname").toString()) + .email(kakao_account.get("email").toString()) + .build(); + } + + private String getAccessToken(String code) { + MultiValueMap params = new LinkedMultiValueMap<>(); + params.put("grant_type", Collections.singletonList("authorization_code")); + params.put("client_id", Collections.singletonList(clientId)); + params.put("redirect_uri", Collections.singletonList(redirectUri)); + params.put("code", Collections.singletonList(code)); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + HttpEntity entity = new HttpEntity(params, headers); + + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseNode = restTemplate.exchange(tokenUri, HttpMethod.POST, entity, JsonNode.class); + JsonNode accessTokenNode = responseNode.getBody(); + + return accessTokenNode.get("access_token").asText(); + } + + private Map getUserInfoAttributes(String accessToken) { + HttpHeaders headers = new HttpHeaders(); + headers.setBearerAuth(accessToken); + HttpEntity entity = new HttpEntity<>(headers); + RestTemplate restTemplate = new RestTemplate(); + return restTemplate.exchange(userinfoUrl, HttpMethod.GET, entity, Map.class).getBody(); + } + +}