---
title: "sdk/java"
description: "네트워크 호출 없는 JWT 검증, HTTP 요청 인증, webhook 서명 검증을 위한 Java 17+ 서버 SDK."
locale: "ko"
---

> Documentation Index
> Fetch the relevant documentation index at: https://vonvon.id/ko/sdks/llms.txt
> Use this file to discover all available pages before exploring further.

# sdk/java

## 상태

로컬에서 구현 및 검증되었습니다. 실제 IdP 왕복 검증(JWKS 가져오기, 실제 Vonvon 인스턴스에 대한 토큰 서명/검증)은 아직 수행되지 않았으며 프로덕션 사용 전에 완료되어야 합니다.

Registry 상태: UNPUBLISHED. 이 SDK는 저장소 소스 checkout에서만 설치하고 외부 package registry를 사용하지 마세요.

요청 인증은 기본적으로 Bearer만 허용합니다. 애플리케이션 소유 JWT cookie는 정확한 이름을 설정한 경우에만 읽습니다. 불투명한 \_\_Host-vonvon.rt.\* Core cookie는 스캔하거나 로컬에서 검증하지 않습니다. 전체 Cookie header를 redirect가 비활성화된 exact same-origin POST /v1/sessions/token으로 전달해 교환하고 token 필드만 포함한 응답만 허용하세요.

## 설치

Java 17 이상과 Maven이 필요합니다.

```xml
<!-- First install the source checkout: cd sdk/java && mvn install -->
<dependency>
  <groupId>dev.vonvon</groupId>
  <artifactId>vonvon-sdk-java</artifactId>
  <version>0.1.0-alpha.0</version>
</dependency>
```

## 빠른 시작

애플리케이션 시작 시 `VonvonClient`를 하나 생성하여 싱글턴으로 사용하세요.

```java
import dev.vonvon.sdk.VonvonClient;
import dev.vonvon.sdk.VonvonClientOptions;
import dev.vonvon.sdk.VonvonClaims;
import dev.vonvon.sdk.VonvonTokenException;
import dev.vonvon.sdk.VonvonJwksException;

VonvonClient vonvon = VonvonClient.create(
VonvonClientOptions.builder()
    .issuer("https://vonvon.id")
    .audience("your-client-id")
    .webhookSecret("whsec_xxx")
    .build()
);

try {
VonvonClaims claims = vonvon.verifyToken(accessToken);
String userId = claims.getSub();
String scope  = claims.getScope();
} catch (VonvonTokenException e) {
response.sendError(401, "Unauthorized: " + e.getReason());
} catch (VonvonJwksException e) {
response.sendError(503, "Service unavailable");
}
```

## HTTP 요청 인증

```java
import dev.vonvon.sdk.AuthResult;

// Bearer-only by default
AuthResult result = vonvon.authenticateRequest(request.getHeader("Authorization"), null);

if (result.isAuthenticated()) {
String userId = result.getClaims().get().getSub();
} else {
response.sendError(401);
}

String token = vonvon.exchangeSessionToken(
request.getRequestURL().toString(),
request.getHeader("Cookie"),
"/v1/sessions/token"
);
```

## webhook 검증

```java
import dev.vonvon.sdk.VonvonWebhookException;

byte[] rawBody = request.getInputStream().readAllBytes();
Map<String, String> headers = Map.of(
"svix-id",        request.getHeader("svix-id"),
"svix-timestamp", request.getHeader("svix-timestamp"),
"svix-signature", request.getHeader("svix-signature")
);

try {
vonvon.verifyWebhook(headers, rawBody);
} catch (VonvonWebhookException e) {
response.sendError(400, "Invalid webhook: " + e.getReason());
}
```

## VonvonClientOptions

| 방법 | 기본값 | 설명 |
| --- | --- | --- |
| `.issuer(String)` | 필수 | OIDC issuer; 토큰의 iss와 정확히 일치해야 합니다 |
| `.audience(String)` | `null` | 예상 aud; null이면 검증을 건너뜁니다 |
| `.webhookSecret(String)` | `null` | Webhook 시크릿(`whsec_` 접두사 또는 일반 base64) |
| `.jwksCacheDuration(Duration)` | 1시간 | JWKS 인메모리 캐시 TTL |
| `.clockSkewTolerance(Duration)` | 30초 | exp/nbf 클럭 편차 허용 범위 |
| `.connectTimeout(Duration)` | 5초 | JWKS 가져오기용 HTTP 연결 타임아웃 |
| `.readTimeout(Duration)` | 10초 | JWKS 가져오기용 HTTP 읽기 타임아웃 |

## 플랫폼 참고 사항

- JWT/JWKS 파싱에 `nimbus-jose-jwt`를 사용합니다. ES256이 기본이며 RS256과 PS256이 지원됩니다.
- 모든 공개 API는 동기식이며 스레드 안전합니다.
- SLF4J 퍼사드를 통한 로깅; 구현체(Logback, Log4j2)를 직접 가져오세요.
- 예외 계층 구조: `VonvonException` -&gt; `VonvonTokenException`, `VonvonJwksException`, `VonvonWebhookException`.

Source: https://vonvon.id/ko/sdks/java/index.mdx
