Skip to content

Commit b9cc9e4

Browse files
authored
Merge pull request #115 from P-ProjectGC/feat/#56/카카오액세스토큰구조
Feat/#56/카카오 액세스 토큰 구조
2 parents 1de7c67 + 7407ca4 commit b9cc9e4

4 files changed

Lines changed: 50 additions & 11 deletions

File tree

src/main/java/plango/auth/application/dto/request/KakaoLoginRequest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
/**
66
* 카카오 로그인 요청 DTO
7-
* - authorizationCode : 카카오 인가 코드 (authorization_code)
7+
* Android 카카오 SDK에서 발급받은 accessToken, idToken을 전달합니다.
8+
* idToken은 선택값이며 현재 서버에서는 accessToken을 기반으로 카카오 사용자 정보를 조회합니다.
89
*/
910
public record KakaoLoginRequest(
10-
@NotBlank(message = "카카오 인가 코드는 필수입니다.")
11-
String authorizationCode
11+
@NotBlank(message = "카카오 access token은 필수입니다.")
12+
String accessToken,
13+
String idToken
1214
) {
1315
}
16+

src/main/java/plango/auth/application/usecase/KakaoLoginUseCase.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ public class KakaoLoginUseCase {
2727

2828
@Transactional
2929
public KakaoLoginResponse execute(KakaoLoginRequest request) {
30-
KakaoUserInfoResponse userInfo = kakaoAuthService.getUserInfoByAuthorizationCode(
31-
request.authorizationCode()
30+
KakaoUserInfoResponse userInfo = kakaoAuthService.getUserInfoByAccessToken(
31+
request.accessToken()
3232
);
3333

3434
String email = userInfo.getEmail();
@@ -70,3 +70,4 @@ public KakaoLoginResponse execute(KakaoLoginRequest request) {
7070
);
7171
}
7272
}
73+

src/main/java/plango/auth/domain/service/KakaoAuthService.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package plango.auth.domain.service;
22

3+
import jakarta.annotation.PostConstruct;
34
import lombok.RequiredArgsConstructor;
45
import lombok.extern.slf4j.Slf4j;
56
import org.springframework.beans.factory.annotation.Value;
@@ -19,15 +20,12 @@
1920
import plango.global.common.exception.BusinessException;
2021
import plango.global.common.exception.ErrorCode;
2122

22-
import jakarta.annotation.PostConstruct;
23-
2423
@Slf4j
2524
@Service
2625
@RequiredArgsConstructor
2726
public class KakaoAuthService {
2827

2928
private static final String KAKAO_TOKEN_URI = "https://kauth.kakao.com/oauth/token";
30-
3129
private static final String KAKAO_USER_INFO_URI = "https://kapi.kakao.com/v2/user/me";
3230

3331
@Value("${security.oauth2.kakao.client-id}")
@@ -45,57 +43,80 @@ public void printConfig() {
4543
log.info("redirectUri = {}", redirectUri);
4644
}
4745

46+
/**
47+
* (웹용) 인가 코드를 이용해 카카오 사용자 정보를 조회하는 메서드
48+
*/
4849
public KakaoUserInfoResponse getUserInfoByAuthorizationCode(String authorizationCode) {
4950
KakaoTokenResponse tokenResponse = requestToken(authorizationCode);
5051
String accessToken = tokenResponse.accessToken();
5152
log.info("accessToken from Kakao = {}", accessToken);
5253
return requestUserInfo(accessToken);
5354
}
5455

56+
/**
57+
* (모바일용) 이미 발급받은 accessToken 으로 바로 사용자 정보 조회
58+
*/
59+
public KakaoUserInfoResponse getUserInfoByAccessToken(String accessToken) {
60+
return requestUserInfo(accessToken);
61+
}
62+
5563
private KakaoTokenResponse requestToken(String authorizationCode) {
5664
HttpHeaders headers = new HttpHeaders();
5765
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
66+
5867
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
5968
body.add("grant_type", "authorization_code");
6069
body.add("client_id", clientId);
6170
body.add("redirect_uri", redirectUri);
6271
body.add("code", authorizationCode);
72+
6373
log.info("requestToken() body = {}", body);
74+
6475
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(body, headers);
76+
6577
try {
6678
ResponseEntity<KakaoTokenResponse> response = restTemplate.postForEntity(
6779
KAKAO_TOKEN_URI,
6880
entity,
6981
KakaoTokenResponse.class
7082
);
83+
7184
log.info("requestToken() status = {}", response.getStatusCode());
85+
7286
KakaoTokenResponse tokenResponse = response.getBody();
87+
7388
if (!response.getStatusCode().is2xxSuccessful() || tokenResponse == null) {
7489
throw new BusinessException(
7590
ErrorCode.KAKAO_SERVER_ERROR.getStatusCode(),
7691
ErrorCode.KAKAO_SERVER_ERROR.getMessage()
7792
);
7893
}
94+
7995
if (tokenResponse.accessToken() == null || tokenResponse.accessToken().isBlank()) {
8096
log.error("Kakao token response has no access_token. body = {}", tokenResponse);
8197
throw new BusinessException(
8298
ErrorCode.KAKAO_SERVER_ERROR.getStatusCode(),
8399
ErrorCode.KAKAO_SERVER_ERROR.getMessage()
84100
);
85101
}
102+
86103
return tokenResponse;
87104
} catch (RestClientResponseException exception) {
88-
log.error("Kakao token request error. status = {}, body = {}",
105+
log.error(
106+
"Kakao token request error. status = {}, body = {}",
89107
exception.getRawStatusCode(),
90108
exception.getResponseBodyAsString()
91109
);
110+
92111
ErrorCode errorCode = selectErrorCode(exception.getRawStatusCode());
112+
93113
throw new BusinessException(
94114
errorCode.getStatusCode(),
95115
errorCode.getMessage()
96116
);
97117
} catch (RestClientException exception) {
98118
log.error("Kakao token request RestClientException", exception);
119+
99120
throw new BusinessException(
100121
ErrorCode.KAKAO_SERVER_ERROR.getStatusCode(),
101122
ErrorCode.KAKAO_SERVER_ERROR.getMessage()
@@ -106,34 +127,43 @@ private KakaoTokenResponse requestToken(String authorizationCode) {
106127
private KakaoUserInfoResponse requestUserInfo(String accessToken) {
107128
HttpHeaders headers = createBearerHeaders(accessToken);
108129
HttpEntity<Void> entity = new HttpEntity<>(headers);
130+
109131
try {
110132
ResponseEntity<KakaoUserInfoResponse> response = restTemplate.exchange(
111133
KAKAO_USER_INFO_URI,
112134
HttpMethod.GET,
113135
entity,
114136
KakaoUserInfoResponse.class
115137
);
138+
116139
log.info("requestUserInfo() status = {}", response.getStatusCode());
140+
117141
KakaoUserInfoResponse userInfo = response.getBody();
142+
118143
if (!response.getStatusCode().is2xxSuccessful() || userInfo == null) {
119144
throw new BusinessException(
120145
ErrorCode.KAKAO_SERVER_ERROR.getStatusCode(),
121146
ErrorCode.KAKAO_SERVER_ERROR.getMessage()
122147
);
123148
}
149+
124150
return userInfo;
125151
} catch (RestClientResponseException exception) {
126-
log.error("Kakao userInfo request error. status = {}, body = {}",
152+
log.error(
153+
"Kakao userInfo request error. status = {}, body = {}",
127154
exception.getRawStatusCode(),
128155
exception.getResponseBodyAsString()
129156
);
157+
130158
ErrorCode errorCode = selectErrorCode(exception.getRawStatusCode());
159+
131160
throw new BusinessException(
132161
errorCode.getStatusCode(),
133162
errorCode.getMessage()
134163
);
135164
} catch (RestClientException exception) {
136165
log.error("Kakao userInfo request RestClientException", exception);
166+
137167
throw new BusinessException(
138168
ErrorCode.KAKAO_SERVER_ERROR.getStatusCode(),
139169
ErrorCode.KAKAO_SERVER_ERROR.getMessage()
@@ -152,6 +182,8 @@ private ErrorCode selectErrorCode(int statusCode) {
152182
if (statusCode == 401) {
153183
return ErrorCode.KAKAO_INVALID_TOKEN;
154184
}
185+
155186
return ErrorCode.KAKAO_SERVER_ERROR;
156187
}
157188
}
189+

src/main/java/plango/auth/presentation/AuthController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@ public ResponseEntity<CommonResponse<KakaoLoginResponse>> login(
9494
);
9595
}
9696

97-
@Operation(summary = "카카오 로그인", description = "카카오 인가 코드를 사용해 로그인합니다.")
97+
@Operation(
98+
summary = "카카오 로그인",
99+
description = "Android 카카오 SDK에서 발급받은 accessToken을 사용해 로그인합니다."
100+
)
98101
@PostMapping("/login/kakao")
99102
public ResponseEntity<CommonResponse<KakaoLoginResponse>> kakaoLogin(
100103
@Valid

0 commit comments

Comments
 (0)