Skip to content

Commit 4993ada

Browse files
committed
💡 Apple 인증 디버깅용 로그 추가
ref: #145
1 parent e0bb697 commit 4993ada

File tree

4 files changed

+68
-102
lines changed

4 files changed

+68
-102
lines changed

src/main/java/com/boggle_boggle/bbegok/oauth/client/AppleJwtGenerator.java

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/main/java/com/boggle_boggle/bbegok/oauth/client/AppleTokenClient.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/main/java/com/boggle_boggle/bbegok/oauth/client/AppleUserInfoClient.java

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,95 @@
11
package com.boggle_boggle.bbegok.oauth.client.impl;
22

3-
import com.boggle_boggle.bbegok.oauth.client.AppleTokenClient;
4-
import com.boggle_boggle.bbegok.oauth.client.AppleUserInfoClient;
3+
import com.auth0.jwt.JWT;
4+
import com.auth0.jwt.algorithms.Algorithm;
5+
import com.boggle_boggle.bbegok.config.properties.OAuthProperties;
56
import com.boggle_boggle.bbegok.oauth.client.OAuth2ProviderClient;
67
import com.boggle_boggle.bbegok.oauth.client.response.AppleTokenResponse;
78
import com.boggle_boggle.bbegok.oauth.info.OAuth2UserInfo;
89
import com.boggle_boggle.bbegok.oauth.info.impl.AppleOAuth2UserInfo;
10+
import com.fasterxml.jackson.core.type.TypeReference;
11+
import com.fasterxml.jackson.databind.ObjectMapper;
912
import lombok.RequiredArgsConstructor;
13+
import lombok.extern.slf4j.Slf4j;
14+
import org.springframework.http.HttpHeaders;
15+
import org.springframework.http.MediaType;
1016
import org.springframework.stereotype.Component;
17+
import org.springframework.web.reactive.function.BodyInserters;
18+
import org.springframework.web.reactive.function.client.WebClient;
1119

20+
import java.io.IOException;
21+
import java.nio.charset.StandardCharsets;
22+
import java.security.interfaces.ECPrivateKey;
23+
import java.time.Instant;
24+
import java.util.Base64;
25+
import java.util.Date;
1226
import java.util.Map;
1327

1428
@Component
1529
@RequiredArgsConstructor
30+
@Slf4j
1631
public class AppleOAuth2Client implements OAuth2ProviderClient {
1732

18-
private final AppleTokenClient appleTokenClient; // 애플은 비동기/JWT 토큰 생성 등 별도 로직 필요
19-
private final AppleUserInfoClient appleUserInfoClient;
20-
private String cachedIdToken; // id_token 저장
33+
private final OAuthProperties oAuthProperties;
34+
private final ObjectMapper objectMapper;
35+
private final ECPrivateKey privateKey; //p8로 로그인용 JWT(액세스토큰) 개인키 만듦
2136

37+
private String cachedIdToken;
38+
39+
//콜백 code를 기반으로 access_token + id_token 발급
2240
@Override
2341
public String requestAccessToken(String code) {
24-
AppleTokenResponse tokenResponse = appleTokenClient.getToken(code);
42+
log.info("[Apple] access_token 요청 시작");
43+
44+
String clientSecret = generateClientSecret();
45+
46+
AppleTokenResponse tokenResponse = WebClient.create()
47+
.post()
48+
.uri(oAuthProperties.getApple().getTokenUri())
49+
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
50+
.body(BodyInserters.fromFormData("grant_type", "authorization_code")
51+
.with("code", code)
52+
.with("client_id", oAuthProperties.getApple().getClientId())
53+
.with("client_secret", clientSecret)
54+
.with("redirect_uri", oAuthProperties.getApple().getRedirectUri()))
55+
.retrieve()
56+
.bodyToMono(AppleTokenResponse.class)
57+
.block();
58+
2559
this.cachedIdToken = tokenResponse.getIdToken();
2660
return tokenResponse.getAccessToken();
2761
}
2862

63+
//id_token 파싱하여 사용자 정보 추출
2964
@Override
3065
public OAuth2UserInfo requestUserInfo(String accessToken) {
31-
Map<String, Object> attributes = appleUserInfoClient.getUserInfo(cachedIdToken);
66+
Map<String, Object> attributes = decodeIdToken(cachedIdToken);
3267
return new AppleOAuth2UserInfo(attributes);
3368
}
69+
70+
//JWT 기반 client_secret 생성
71+
private String generateClientSecret() {
72+
Instant now = Instant.now();
73+
Instant exp = now.plusSeconds(3600);
74+
75+
return JWT.create()
76+
.withIssuer(oAuthProperties.getApple().getTeamId())
77+
.withSubject(oAuthProperties.getApple().getClientId())
78+
.withAudience(oAuthProperties.getApple().getIss())
79+
.withIssuedAt(Date.from(now))
80+
.withExpiresAt(Date.from(exp))
81+
.withKeyId(oAuthProperties.getApple().getKeyId())
82+
.sign(Algorithm.ECDSA256(null, privateKey));
83+
}
84+
85+
//Base64 + JSON 파싱으로 user info 추출
86+
private Map<String, Object> decodeIdToken(String idToken) {
87+
try {
88+
String[] parts = idToken.split("\\.");
89+
String payloadJson = new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8);
90+
return objectMapper.readValue(payloadJson, new TypeReference<>() {});
91+
} catch (IOException e) {
92+
throw new RuntimeException("Apple ID Token 디코딩 실패", e);
93+
}
94+
}
3495
}

0 commit comments

Comments
 (0)