-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathKakaoOAuthClient.java
More file actions
96 lines (85 loc) · 3.94 KB
/
KakaoOAuthClient.java
File metadata and controls
96 lines (85 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.example.solidconnection.auth.client;
import static com.example.solidconnection.common.exception.ErrorCode.INVALID_OR_EXPIRED_KAKAO_AUTH_CODE;
import static com.example.solidconnection.common.exception.ErrorCode.KAKAO_REDIRECT_URI_MISMATCH;
import static com.example.solidconnection.common.exception.ErrorCode.KAKAO_USER_INFO_FAIL;
import com.example.solidconnection.auth.client.config.KakaoOAuthClientProperties;
import com.example.solidconnection.auth.dto.oauth.KakaoTokenDto;
import com.example.solidconnection.auth.dto.oauth.KakaoUserInfoDto;
import com.example.solidconnection.auth.dto.oauth.OAuthUserInfoDto;
import com.example.solidconnection.auth.service.oauth.OAuthClient;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.AuthType;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
/*
* - 카카오 인증을 위한 OAuth2 클라이언트
* - https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#request-code
* - https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#request-token
* - https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#req-user-info
* - OAuthClient 인터페이스를 사용하는 전략 패턴으로 구현됨
* */
@Component
@RequiredArgsConstructor
public class KakaoOAuthClient implements OAuthClient {
private final RestTemplate restTemplate;
private final KakaoOAuthClientProperties kakaoOAuthClientProperties;
@Override
public AuthType getAuthType() {
return AuthType.KAKAO;
}
@Override
public OAuthUserInfoDto getUserInfo(String code) {
String kakaoAccessToken = getKakaoAccessToken(code);
return getKakaoUserInfo(kakaoAccessToken);
}
private String getKakaoAccessToken(String code) {
try {
ResponseEntity<KakaoTokenDto> response = restTemplate.exchange(
buildTokenUri(code),
HttpMethod.POST,
null,
KakaoTokenDto.class
);
return Objects.requireNonNull(response.getBody()).accessToken();
} catch (Exception e) {
if (e.getMessage().contains("KOE303")) {
throw new CustomException(KAKAO_REDIRECT_URI_MISMATCH);
}
if (e.getMessage().contains("KOE320")) {
throw new CustomException(INVALID_OR_EXPIRED_KAKAO_AUTH_CODE);
}
throw new CustomException(INVALID_OR_EXPIRED_KAKAO_AUTH_CODE);
}
}
private String buildTokenUri(String code) {
return UriComponentsBuilder.fromHttpUrl(kakaoOAuthClientProperties.tokenUrl())
.queryParam("grant_type", "authorization_code")
.queryParam("client_id", kakaoOAuthClientProperties.clientId())
.queryParam("redirect_uri", kakaoOAuthClientProperties.redirectUrl())
.queryParam("code", code)
.toUriString();
}
private KakaoUserInfoDto getKakaoUserInfo(String accessToken) {
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(accessToken);
ResponseEntity<KakaoUserInfoDto> response = restTemplate.exchange(
kakaoOAuthClientProperties.userInfoUrl(),
HttpMethod.GET,
new HttpEntity<>(headers),
KakaoUserInfoDto.class
);
if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
return response.getBody();
} else {
throw new CustomException(KAKAO_USER_INFO_FAIL);
}
}
}