---
title: "@vonvon-kit/react-native"
description: "用于 Hosted Auth 重定向、PKCE S256、deep-link callback 和安全 token 存储适配器的 React Native provider 和 hook。"
locale: "zh-Hans"
---

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

# @vonvon-kit/react-native

## 状态

Registry 状态:UNPUBLISHED。此 SDK 只能从仓库源码 checkout 安装；不要使用外部 package registry。

Package 状态为**当前 package**。它实现原生 token-session contract：使用 PKCE S256 的 Hosted Auth redirect、在 deep-link callback 上验证 state 和 nonce、验证 ID token claims、交换 authorization code，并通过注入的 storage adapter 持久化 secure session。

在真实生产基础设施上的 IdP 往返验证仍待人工核实。本页面记录已实现的行为，不代表生产就绪声明。

## Provider 配置

将 `TokenCache`（平台安全存储）和 `BrowserInterface`（应用内浏览器）注入 `VonvonProvider`。SDK 不硬绑定任何原生模块；Expo 应用可使用 [@vonvon-kit/expo](/zh-hans/sdks/expo) 中的现成适配器。

```tsx
import { VonvonProvider } from '@vonvon-kit/react-native'
import type { BrowserInterface, TokenCache } from '@vonvon-kit/react-native'
import * as Keychain from 'react-native-keychain'

const tokenCache: TokenCache = {
  async getToken(key) {
const result = await Keychain.getGenericPassword({ service: key })
return result ? result.password : null
  },
  async saveToken(key, value) {
await Keychain.setGenericPassword('vonvon', value, { service: key })
  },
  async deleteToken(key) {
await Keychain.resetGenericPassword({ service: key })
  },
}

const browser: BrowserInterface = {
  async openAuthSession(url, redirectUri) {
// Open url with your in-app browser library, wait for the redirectUri
// deep link, then return { type: 'success', url } or { type: 'cancel' }.
throw new Error('Implement with your preferred in-app browser library.')
  },
}

export function App() {
  return (
<VonvonProvider
  issuer="https://vonvon.id"
  clientId="your_client_id"
  redirectUri="myapp://auth/callback"
  tokenCache={tokenCache}
  browser={browser}
>
  <RootNavigator />
</VonvonProvider>
  )
}
```

## 登录

`signIn()` 会构建 PKCE S256 authorize URL，将 verifier、OAuth state 和 nonce 存入 token cache，打开 browser adapter，并用返回的 code 换取已验证的原生会话。浏览器失败、state 不匹配、ID token 验证和 token exchange 错误会体现为 `signInState.status === 'error'`。

```tsx
import { useSignIn } from '@vonvon-kit/react-native'

function SignInScreen() {
  const { signIn, signInState } = useSignIn()

  return (
<Button
  title={signInState.status === 'pending' ? 'Signing in...' : 'Sign in'}
  onPress={() => void signIn()}
/>
  )
}
```

## 深度链接回调

当 browser adapter 无法自行捕获 redirect 时，请在 app manifest 中注册 redirect URI scheme，并将 deep link 转发给 `handleRedirect(url)`。它会验证并消费 OAuth state、verifier 和 nonce，交换 code，验证 ID token，并存储原生会话。

```tsx
import { useSignIn } from '@vonvon-kit/react-native'
import { useEffect } from 'react'
import { Linking } from 'react-native'

function DeepLinkHandler() {
  const { handleRedirect } = useSignIn()

  useEffect(() => {
const sub = Linking.addEventListener('url', ({ url }) => {
  if (url.startsWith('myapp://auth/callback')) {
    void handleRedirect(url)
  }
})
return () => sub.remove()
  }, [handleRedirect])

  return null
}
```

## 导出的 API

| 导出 | 类型 | 用途 |
| --- | --- | --- |
| `VonvonProvider` | 组件 | 使用 tokenCache、browser、issuer、clientId、redirectUri、scopes 和可选 fetcher 提供原生 token-session context |
| `useSignIn` | hook | signIn(options?) 运行完整重定向流程；handleRedirect(url) 处理 deep-link callback；signInState 报告 idle、pending、complete、cancelled 或 error 状态 |
| `useSignOut` | hook | signOut() 会清除本地会话和 legacy credentials；signOutState 报告进度或 storage failures；不会发送 revoke request |
| `useVonvonRnContext` | hook | 原始适配器上下文（高级用法和测试） |
| `exchangeCodeForTokens` | function | 使用 grant\_type authorization\_code 和 PKCE verifier 向 token 端点发起底层 POST；返回 TokenSet |
| `saveTokenSet / clearTokenSet` | 函数 | 在 TokenCache 适配器中持久化或删除 token 集 |
| `TOKEN_KEYS` | as const 对象 | 当前 session envelope 以及待处理的 PKCE、state 和 nonce records 所用的 TokenCache key names；legacy token keys 仅用于清理 |
| `createPkceVerifier / createPkceChallenge` | 函数 | PKCE S256 工具委托给 @vonvon-kit/protocol（Web Crypto） |
| `createRandomString / base64UrlEncode` | 函数 | OAuth state 的 URL 安全随机字符串；base64url 编码辅助工具 |

## 原生 hooks 和 controls

与 [@vonvon-kit/react](/zh-hans/sdks/react) 不同，此 package 使用自己的原生 token context。它导出 `useAuth`、`useUser`、`useSession`、`useSignIn`、`useSignOut`、`useVonvonRnContext`、`SignedIn`、`SignedOut`、`VonvonLoaded`、`VonvonLoading`、`exchangeCodeForTokens`、`saveTokenSet`、`readTokenSet` 和 `clearTokenSet`；它不会导入或重新导出 React Web SDK。

## 类型

| 类型 | 描述 |
| --- | --- |
| `VonvonProviderProps` | 原生 provider props：children、tokenCache、browser、issuer、clientId、redirectUri、可选 scopes（默认为 openid、profile、email）和可选 fetcher |
| `TokenCache` | 存储适配器契约：getToken、saveToken、deleteToken（均为异步） |
| `BrowserInterface` | openAuthSession(url, redirectUri) 解析为 BrowserResult |
| `BrowserResult` | success（含 callback URL）、cancel 和 dismiss 的联合类型 |
| `SignInOptions` | signIn 的单次调用覆盖选项：redirectUri、scopes |
| `SignInState / SignOutState` | hook 返回的判别状态联合类型 |
| `UseSignInReturn / UseSignOutReturn` | hook 返回结构：操作加状态 |
| `TokenExchangeInput / TokenSet` | exchangeCodeForTokens 的输入和结果：accessToken、idToken、expiresIn 及已验证的 ID token claims |
| `VonvonRnContextValue` | useVonvonRnContext 返回的适配器上下文结构 |

## 已知限制

- SDK 没有 DPoP sender binding，会拒绝 offline\_access，并在 access token 到期后要求执行新的 authorization flow。
- useAuth().isSignedIn 仅在 ID token 验证后才反映本地存储的会话；它不会读取 Web cookie 会话。
- 组织上下文尚未从存储的 token 中填充。

## 安全

- 仅支持带 PKCE S256 的授权码流程，不支持 implicit 或 password grant。
- 公开客户端从不存储客户端密钥。
- PKCE verifier 和 OAuth state 存在于注入的安全存储适配器中，code 交换后删除。
- signOut 会清除本地会话和 legacy credentials，不发送 refresh 或 revoke request；storage failures 会体现在 signOutState 中。

Source: https://vonvon.id/zh-hans/sdks/react-native/index.mdx
