---
title: "@vonvon-kit/tauri"
description: "PKCE S256 흐름, 딥링크 콜백 핸들러, OS keychain 어댑터, Rust 플러그인 템플릿이 있는 Tauri v2 데스크톱 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.

# @vonvon-kit/tauri

## 상태

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

패키지 상태: **현재 패키지**. JS 브리지, PKCE S256 흐름, 딥링크 콜백 핸들러, OS keychain 어댑터, Rust 플러그인 템플릿이 구현되었습니다. 프로덕션 인프라에서의 실제 IdP 왕복 테스트는 아직 수동 검증 대기 중입니다.

## Tauri 설정

```json
// tauri.conf.json
{
  "bundle": { "identifier": "com.example.myapp" },
  "plugins": {
"deep-link": { "desktop": { "schemes": ["myapp"] } }
  }
}
```

## Rust 플러그인

`templates/vonvon-keychain-plugin.rs`를 `src-tauri/src/vonvon_keychain.rs`에 복사하고 `templates/tauri-app-setup.rs`를 참고하여 등록하세요. `src-tauri/Cargo.toml`에 `keyring = \\\"2\\\"`, `tauri-plugin-deep-link = \\\"2\\\"`, `tauri-plugin-shell = \\\"2\\\"`를 추가하세요.

## JS 통합

```ts
import { createVonvonTauriClient, createTauriKeychainAdapter } from '@vonvon-kit/tauri'
import { invoke } from '@tauri-apps/api/core'
import { open } from '@tauri-apps/plugin-shell'
import { onOpenUrl } from '@tauri-apps/plugin-deep-link'

const client = createVonvonTauriClient({
  issuer: 'https://vonvon.id',
  clientId: 'YOUR_CLIENT_ID',
  redirectUri: 'myapp://auth/callback',
  keychain: createTauriKeychainAdapter({ invoke }),
})

// Register deeplink handler (e.g. on App component mount)
await onOpenUrl(async (urls) => {
  for (const url of urls) await client.handleRedirect(url)
})

// Trigger sign-in: opens system browser
await client.signIn({ openUrl: open })
```

## 토큰 검색 및 로그아웃

```ts
// Get the current unexpired access token. Expiry requires a new sign-in.
const token = await client.getAccessToken()

// Get the current unexpired session (userId, organizationId, expiresAt).
const session = await client.getSession()

// Clear local keychain state. No refresh or revoke request is sent.
await client.signOut()

// To request full IdP sign-out, open an explicit OIDC RP-initiated logout URL.
const logoutUrl = client.buildSignOutUrl({ postLogoutRedirectUri: 'myapp://logout' })
await open(logoutUrl.toString())
```

## Tauri 런타임 없이 개발/테스트

```ts
import { createVonvonTauriClient, createMemoryKeychainAdapter } from '@vonvon-kit/tauri'

const client = createVonvonTauriClient({
  issuer: 'http://localhost:8788',
  clientId: 'test-client',
  redirectUri: 'http://localhost:1420/callback',
  keychain: createMemoryKeychainAdapter(),
})
```

## createVonvonTauriClient 옵션

| 옵션 | 유형 | 설명 |
| --- | --- | --- |
| `issuer` | string | Vonvon 발급자 URL |
| `clientId` | string | OAuth 2.0 client\_id |
| `redirectUri` | string | 사용자 정의 URI 스킴 콜백 |
| `scopes` | readonly string\[\] | 기본값: openid, profile, email |
| `keychain` | VonvonKeychainAdapter | 토큰 저장소 어댑터; 기본값은 MemoryKeychainAdapter입니다(프로덕션에서는 Tauri 어댑터 사용) |

## VonvonTauriClient 메서드

| 방법 | 설명 |
| --- | --- |
| `signIn(options?)` | PKCE 인증 URL 생성; openUrl 콜백을 통해 엽니다 |
| `handleRedirect(url)` | 딥링크를 파싱하고 state를 검증하며 코드를 토큰으로 교환합니다 |
| `getSession()` | 현재 만료되지 않은 로컬 session이면 TauriSession, 아니면 null입니다. 만료된 state는 지워집니다. |
| `getAccessToken(options?)` | 현재 만료되지 않은 access token 문자열 또는 null입니다. refresh request는 수행하지 않습니다. DPoP가 구현될 때까지 SDK는 offline\_access를 거부합니다. |
| `signOut()` | revoke request 없이 로컬 keychain state 지우기 |
| `buildSignOutUrl(options?)` | RP 주도 로그아웃을 위한 OIDC end\_session URL 생성 |
| `setTokenStorage(adapter)` | 런타임에 keychain 어댑터 교체 |

## PKCE 및 토큰 저장소

- PKCE S256이 항상 사용됩니다. Plain challenge는 절대 생성되지 않습니다.
- 검증자 엔트로피는 64바이트입니다. challenge는 Web Crypto `crypto.subtle.digest('SHA-256', ...)`를 통해 파생됩니다.
- 모든 key는 `vonvon.*` namespace에 속합니다. 현재 사용하는 key는 `vonvon.access_token`입니다. `vonvon.refresh_token`은 legacy cleanup 용도로만 삭제됩니다. `vonvon.session`, `vonvon.pkce_verifier`, `vonvon.oauth_state`에는 현재 session과 authorization state가 저장되며 refresh credential을 읽거나 쓰지 않습니다.

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