Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.nimbusds.jose.jwk.source.RemoteJWKSet;
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
import com.nimbusds.jose.proc.SecurityContext;
import com.nimbusds.jose.util.DefaultResourceRetriever;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
import com.nimbusds.jwt.proc.DefaultJWTProcessor;
Expand Down Expand Up @@ -52,6 +53,10 @@ public class AppleSignInService {
@Value("${apple.revoke-url}")
private String APPLE_REVOKE_URL;
private static final String APPLE_JWKS_URL = "https://appleid.apple.com/auth/keys";
// 애플 공개키(JWKS) 조회 및 회원탈퇴 통보에 타임아웃을 명시한다. 기본값(무제한 대기)이면
// 애플 쪽이 응답을 늦게 줄 때 이 요청을 처리하던 톰캣 스레드가 계속 묶여있게 된다.
private static final int CONNECT_TIMEOUT_MS = 3000;
private static final int READ_TIMEOUT_MS = 3000;
Comment on lines +56 to +59

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify the default timeout behavior in the declared Nimbus JOSE + JWT version.
curl -fsSL \
  https://repo1.maven.org/maven2/com/nimbusds/nimbus-jose-jwt/9.12/nimbus-jose-jwt-9.12-sources.jar \
  -o /tmp/nimbus-jose-jwt-9.12-sources.jar

unzip -p /tmp/nimbus-jose-jwt-9.12-sources.jar \
  com/nimbusds/jose/jwk/source/RemoteJWKSet.java |
  rg -n -C 3 'DEFAULT_HTTP_(CONNECT|READ)_TIMEOUT|DefaultResourceRetriever'

Repository: Runnect/Runnect-Spring-Boot-Server

Length of output: 2283


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- dependency declarations ---'
rg -n -C 3 'nimbus-jose-jwt|okhttp' pom.xml build.gradle* gradle.properties 2>/dev/null || true

printf '%s\n' '--- AppleSignInService.java relevant sections ---'
sed -n '1,180p' src/main/java/org/runnect/server/auth/service/AppleSignInService.java

Repository: Runnect/Runnect-Spring-Boot-Server

Length of output: 8025


Correct the JWKS timeout comment.

Nimbus JOSE + JWT 9.12 uses 500 ms connect and read timeouts by default. Remove the statement that JWKS retrieval can wait indefinitely.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/runnect/server/auth/service/AppleSignInService.java` around
lines 56 - 59, Update the comment above CONNECT_TIMEOUT_MS and READ_TIMEOUT_MS
to accurately state that Nimbus JOSE + JWT 9.12 provides 500 ms default connect
and read timeouts; remove the claim that the default is unlimited or that JWKS
retrieval can wait indefinitely.


private PrivateKey PRIVATE_KEY;
@Value("${apple.p8key}")
Expand Down Expand Up @@ -109,7 +114,9 @@ public SocialInfoResponseDto getSocialInfo(String idToken) {
}

private JWTClaimsSet verifySignatureAndGetClaims(String idToken) throws Exception {
JWKSource<SecurityContext> keySource = new RemoteJWKSet<>(new URL(APPLE_JWKS_URL));
JWKSource<SecurityContext> keySource = new RemoteJWKSet<>(
new URL(APPLE_JWKS_URL),
new DefaultResourceRetriever(CONNECT_TIMEOUT_MS, READ_TIMEOUT_MS));
ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
JWSVerificationKeySelector<SecurityContext> keySelector =
new JWSVerificationKeySelector<>(JWSAlgorithm.RS256, keySource);
Expand Down Expand Up @@ -137,7 +144,11 @@ public void reportWithdrawalToApple(String appleAccessToken) {

String clientSecret = createClientSecret();

OkHttpClient client = new OkHttpClient();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(CONNECT_TIMEOUT_MS, java.util.concurrent.TimeUnit.MILLISECONDS)
.readTimeout(READ_TIMEOUT_MS, java.util.concurrent.TimeUnit.MILLISECONDS)
.writeTimeout(READ_TIMEOUT_MS, java.util.concurrent.TimeUnit.MILLISECONDS)
.build();

RequestBody formBody = new FormBody.Builder()
.add("token", appleAccessToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
Expand All @@ -21,14 +22,20 @@
@RequiredArgsConstructor
public class KakaoSignInService {

// 기본 RestTemplate은 타임아웃이 없어(무제한 대기), 카카오가 응답을 늦게 주면
// 그 요청을 처리하던 톰캣 스레드가 계속 묶여있게 된다. 스레드 풀이 이런 식으로
// 소진되면 카카오 로그인과 무관한 다른 API 요청까지 영향을 받는다.
private static final int CONNECT_TIMEOUT_MS = 3000;
private static final int READ_TIMEOUT_MS = 3000;

public SocialInfoResponseDto getSocialInfo(String token) {

HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + token);
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

HttpEntity<MultiValueMap<String, String>> kakaoUserInfoRequest = new HttpEntity<>(headers);
RestTemplate rt = new RestTemplate();
RestTemplate rt = new RestTemplate(createTimeoutRequestFactory());

String userId = null;
String email = null;
Expand Down Expand Up @@ -61,4 +68,11 @@ public SocialInfoResponseDto getSocialInfo(String token) {
}
return SocialInfoResponseDto.of(email, userId);
}

private SimpleClientHttpRequestFactory createTimeoutRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(CONNECT_TIMEOUT_MS);
factory.setReadTimeout(READ_TIMEOUT_MS);
return factory;
}
}
Loading