Skip to content

Commit 2218f8a

Browse files
committed
fix: support native iOS Apple login
1 parent f2c39b9 commit 2218f8a

3 files changed

Lines changed: 37 additions & 10 deletions

File tree

ontime-back/src/main/java/devkor/ontime_back/global/oauth/apple/AppleLoginFilter.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ
9797
}
9898

9999
} catch (Exception e) {
100-
log.error("Apple login failed: {}", e.getClass().getSimpleName());
101-
throw new AuthenticationException("Apple 로그인 실패") {};
100+
log.error("Apple login failed", e);
101+
throw new AppleLoginException();
102102
}
103103
}
104104

@@ -109,7 +109,9 @@ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServle
109109
return;
110110
}
111111
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
112-
response.getWriter().write("{\"status\":\"error\", \"message\":\"Authentication failed\"}");
112+
response.setContentType("application/json");
113+
response.setCharacterEncoding("UTF-8");
114+
response.getWriter().write("{\"status\":\"error\", \"message\":\"Apple 로그인 실패\"}");
113115
}
114116

115117
private static class RequestValidationException extends AuthenticationException {
@@ -118,4 +120,10 @@ private RequestValidationException() {
118120
}
119121
}
120122

123+
private static class AppleLoginException extends AuthenticationException {
124+
private AppleLoginException() {
125+
super("Apple login failed");
126+
}
127+
}
128+
121129
}

ontime-back/src/main/java/devkor/ontime_back/global/oauth/apple/AppleLoginService.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public class AppleLoginService {
5151

5252
private static final String APPLE_KEYS_URL = "https://appleid.apple.com/auth/keys";
5353
private static final String APPLE_TOKEN_URL = "https://appleid.apple.com/auth/token";
54-
private static final String REDIRECT_URI = "https://ontime-back.duckdns.org/oauth2/apple/callback";
5554
private String issuer = "https://appleid.apple.com";
5655
@Value("${apple.client.id}")
5756
private String clientId;
@@ -198,12 +197,7 @@ public AppleTokenResponseDto getAppleAccessTokenAndRefreshToken(String authCode)
198197
// clientSecret
199198
String clientSecret = generateClientSecret();
200199
log.info("Exchange Apple credential");
201-
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
202-
requestBody.add("grant_type", "authorization_code");
203-
requestBody.add("code", authCode);
204-
requestBody.add("client_id", clientId);
205-
requestBody.add("client_secret", clientSecret);
206-
requestBody.add("redirect_uri", REDIRECT_URI);
200+
MultiValueMap<String, String> requestBody = buildAppleTokenRequestBody(authCode, clientSecret);
207201

208202
HttpHeaders headers = new HttpHeaders();
209203
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
@@ -219,6 +213,15 @@ public AppleTokenResponseDto getAppleAccessTokenAndRefreshToken(String authCode)
219213
return objectMapper.treeToValue(response, AppleTokenResponseDto.class);
220214
}
221215

216+
MultiValueMap<String, String> buildAppleTokenRequestBody(String authCode, String clientSecret) {
217+
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
218+
requestBody.add("grant_type", "authorization_code");
219+
requestBody.add("code", authCode);
220+
requestBody.add("client_id", clientId);
221+
requestBody.add("client_secret", clientSecret);
222+
return requestBody;
223+
}
224+
222225
// clientsecret 생성
223226
private String generateClientSecret() throws Exception {
224227
log.info("Generate Apple client credential");

ontime-back/src/test/java/devkor/ontime_back/global/oauth/apple/AppleLoginServiceTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.security.core.Authentication;
2929
import org.springframework.security.core.context.SecurityContextHolder;
3030
import org.springframework.test.util.ReflectionTestUtils;
31+
import org.springframework.util.MultiValueMap;
3132
import org.springframework.web.client.HttpClientErrorException;
3233
import org.springframework.web.client.RestTemplate;
3334

@@ -223,6 +224,21 @@ void getAppleAccessTokenAndRefreshTokenExchangesAuthCodeWithClientSecret() throw
223224
assertThat(response.getIdToken()).isEqualTo("identity-token");
224225
}
225226

227+
@Test
228+
void nativeAppleTokenRequestDoesNotIncludeRedirectUri() {
229+
ReflectionTestUtils.setField(appleLoginService, "clientId", "club.devkor.ontime.ios");
230+
231+
MultiValueMap<String, String> body = appleLoginService.buildAppleTokenRequestBody(
232+
"apple-auth-code",
233+
"apple-client-secret");
234+
235+
assertThat(body).containsEntry("grant_type", java.util.List.of("authorization_code"));
236+
assertThat(body).containsEntry("code", java.util.List.of("apple-auth-code"));
237+
assertThat(body).containsEntry("client_id", java.util.List.of("club.devkor.ontime.ios"));
238+
assertThat(body).containsEntry("client_secret", java.util.List.of("apple-client-secret"));
239+
assertThat(body).doesNotContainKey("redirect_uri");
240+
}
241+
226242
@Test
227243
void revokeTokenReturnsFalseWhenAppleAcceptsCurrentRefreshToken() throws Exception {
228244
RestTemplate restTemplate = mockRestTemplate();

0 commit comments

Comments
 (0)