-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
11 changed files
with
574 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
.../src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.example.backend.auth.api.service.oauth.adapter.kakao; | ||
|
||
import com.example.backend.auth.api.service.oauth.adapter.OAuthAdapter; | ||
import com.example.backend.auth.api.service.oauth.response.OAuthResponse; | ||
import com.example.backend.common.exception.ExceptionMessage; | ||
import com.example.backend.common.exception.oauth.OAuthException; | ||
import com.example.backend.external.clients.oauth.kakao.KakaoProfileClients; | ||
import com.example.backend.external.clients.oauth.kakao.KakaoTokenClients; | ||
import com.example.backend.external.clients.oauth.kakao.response.KakaoProfileResponse; | ||
import com.example.backend.external.clients.oauth.kakao.response.KakaoTokenResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.net.URI; | ||
|
||
import static com.example.backend.domain.define.user.constant.UserPlatformType.KAKAO; | ||
|
||
@Slf4j | ||
@Component | ||
@RequiredArgsConstructor | ||
public class KakaoAdapter implements OAuthAdapter { | ||
private final KakaoTokenClients kakaoTokenClients; | ||
private final KakaoProfileClients kakaoProfileClients; | ||
|
||
@Override | ||
public String getToken(String tokenURL) { | ||
try { | ||
KakaoTokenResponse token = kakaoTokenClients.getToken(URI.create(tokenURL)); | ||
|
||
// 받아온 token이 null일 경우 예외 발생 | ||
if (token.getAccess_token() == null) { | ||
throw new OAuthException(ExceptionMessage.OAUTH_INVALID_TOKEN_URL); | ||
} | ||
|
||
return token.getAccess_token(); | ||
} catch (RuntimeException e) { | ||
log.error(">>>> [ Kakao Oauth 인증 에러 발생: {}", ExceptionMessage.OAUTH_INVALID_TOKEN_URL.getText()); | ||
throw new OAuthException(ExceptionMessage.OAUTH_INVALID_TOKEN_URL); | ||
} | ||
} | ||
|
||
@Override | ||
public OAuthResponse getProfile(String accessToken) { | ||
try { | ||
KakaoProfileResponse profile = kakaoProfileClients.getProfile("Bearer " + accessToken); | ||
|
||
return OAuthResponse.builder() | ||
.platformId(profile.getId().toString()) | ||
.platformType(KAKAO) | ||
.name(profile.getProperties().getNickname()) | ||
.profileImageUrl(profile.getProperties().getProfile_image()) | ||
.build(); | ||
} catch (RuntimeException e) { | ||
log.error(">>>> [ Kakao Oauth 인증 에러 발생: {}", ExceptionMessage.OAUTH_INVALID_ACCESS_TOKEN.getText()); | ||
throw new OAuthException(ExceptionMessage.OAUTH_INVALID_ACCESS_TOKEN); | ||
} | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
...c/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.example.backend.auth.api.service.oauth.builder.kakao; | ||
|
||
import com.example.backend.auth.api.service.oauth.builder.OAuthURLBuilder; | ||
import com.example.backend.auth.config.oauth.OAuthProperties; | ||
import com.example.backend.common.exception.ExceptionMessage; | ||
import com.example.backend.common.exception.oauth.OAuthException; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Slf4j | ||
@Component | ||
public class KakaoURLBuilder implements OAuthURLBuilder { | ||
private static final String PLATFORM = "kakao"; | ||
private final String authorizationUri; | ||
private final String clientId; | ||
private final String redirectUri; | ||
private final String tokenUri; | ||
private final String clientSecret; | ||
private final String profileUri; | ||
|
||
|
||
// 속성에서 읽어온 객체를 주입 | ||
public KakaoURLBuilder(OAuthProperties oAuthProperties) { | ||
try { | ||
// 플랫폼(kakao)의 client, provider Map 획득 | ||
OAuthProperties.Client kakaoClient = oAuthProperties.getClient().get(PLATFORM); | ||
OAuthProperties.Provider kakaoProvider = oAuthProperties.getProvider().get(PLATFORM); | ||
|
||
this.authorizationUri = kakaoProvider.authorizationUri(); | ||
this.clientId = kakaoClient.clientId(); | ||
this.redirectUri = kakaoClient.redirectUri(); | ||
this.tokenUri = kakaoProvider.tokenUri(); | ||
this.clientSecret = kakaoClient.clientSecret(); | ||
this.profileUri = kakaoProvider.profileUri(); | ||
|
||
} catch (NullPointerException e) { | ||
log.error(">>>> OAuthProperties NullPointerException 발생: {}", ExceptionMessage.OAUTH_CONFIG_NULL); | ||
throw new OAuthException(ExceptionMessage.OAUTH_CONFIG_NULL); | ||
} | ||
} | ||
// "https://kauth.kakao.com/oauth/authorize?..." | ||
@Override | ||
public String authorize(String state) { | ||
return authorizationUri | ||
+ "?response_type=code" // OAuth 인증 코드 그랜트 유형: code로 고정 | ||
+ "&client_id=" + clientId // 클라이언트 ID | ||
+ "&redirect_uri=" + redirectUri // 리다이렉트 URI | ||
+ "&state=" + state // CSRF 방지 | ||
+ "&scope=openid"; // 리소스 접근 범위: openid로 고정 | ||
} | ||
|
||
// "https://kauth.kakao.com/oauth/token?..." | ||
@Override | ||
public String token(String code, String state) { | ||
return tokenUri | ||
+ "?grant_type=authorization_code" // OAuth 인증 코드 그랜트 유형: code로 고정 | ||
+ "&client_id=" + clientId // 클라이언트 ID | ||
+ "&client_secret=" + clientSecret // 클라이언트 Secret | ||
+ "&redirect_uri=" + redirectUri // 리다이렉트 URI | ||
+ "&code=" + code; // authorize() 요청으로 얻은 인가 코드 | ||
|
||
} | ||
// "https://kapi.kakao.com/v2/user/me" | ||
@Override | ||
public String profile() { return profileUri; } | ||
} |
17 changes: 17 additions & 0 deletions
17
...d/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoProfileClients.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.example.backend.external.clients.oauth.kakao; | ||
|
||
import com.example.backend.external.annotation.ExternalClients; | ||
import com.example.backend.external.clients.oauth.kakao.response.KakaoProfileResponse; | ||
import org.springframework.web.bind.annotation.RequestHeader; | ||
import org.springframework.web.service.annotation.GetExchange; | ||
|
||
/* | ||
사용자 정보를 얻기 위해 설정한 profile 요청 URI로 GET 요청을 보낸다. | ||
*/ | ||
@ExternalClients(baseUrl = "https://kapi.kakao.com/v2/user/me") | ||
public interface KakaoProfileClients { | ||
|
||
@GetExchange | ||
public KakaoProfileResponse getProfile(@RequestHeader(value = "Authorization") String header); | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
...end/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoTokenClients.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.example.backend.external.clients.oauth.kakao; | ||
|
||
|
||
import com.example.backend.external.annotation.ExternalClients; | ||
import com.example.backend.external.clients.oauth.kakao.response.KakaoTokenResponse; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.web.service.annotation.PostExchange; | ||
|
||
import java.net.URI; | ||
|
||
/* | ||
AccessToken을 얻기 위해 설정한 token URI로 POST 요청을 보낸다. | ||
*/ | ||
@ExternalClients(baseUrl = "oauth2.provider.kakao.token-uri") | ||
public interface KakaoTokenClients { | ||
|
||
// 요청의 content Type: FORM_URLENCODED 형식 ex) key1=value1&key2=value2 | ||
@PostExchange(contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE) | ||
public KakaoTokenResponse getToken(URI uri); | ||
} |
33 changes: 33 additions & 0 deletions
33
.../java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.example.backend.external.clients.oauth.kakao.response; | ||
|
||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public class KakaoProfileResponse { | ||
private Long id; | ||
private String name; | ||
|
||
private Properties properties; | ||
|
||
public KakaoProfileResponse(Long id, String name, Properties properties) { | ||
this.id = id; | ||
this.name = name; | ||
this.properties = properties; | ||
} | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public static class Properties { | ||
private String nickname; | ||
private String profile_image; | ||
private String thumbnail_image; | ||
|
||
public Properties(String nickname, String profile_image, String thumbnail_image) { | ||
this.nickname = nickname; | ||
this.profile_image = profile_image; | ||
this.thumbnail_image = thumbnail_image; | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...in/java/com/example/backend/external/clients/oauth/kakao/response/KakaoTokenResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.example.backend.external.clients.oauth.kakao.response; | ||
|
||
|
||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
/* | ||
Kakao에 Access Token을 요청 후 반환받을 DTO | ||
*/ | ||
@Getter | ||
@NoArgsConstructor | ||
public class KakaoTokenResponse { | ||
private String access_token; | ||
|
||
public KakaoTokenResponse(String access_token) { | ||
this.access_token = access_token; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.