跳到正文

@xid-kit/expo

适用于 @xid-kit/react-native 的 Expo SecureStore 和 WebBrowser 适配器,以及 Expo Router 路由守卫 hook。

状态

包状态为 当前包。Expo SecureStore 和 WebBrowser 适配器、XidProvider 及 Expo Router 路由守卫 hook 已实现。在真实生产基础设施上的 IdP 往返验证仍待人工核实。

所有 PKCE 逻辑、token 交换和会话管理均在 @xid-kit/react-native 中;此包仅提供适配器和 Expo Router 集成。

Provider 配置

createSecureStoreAdaptercreateExpoWebBrowserAdapter 注入 XidProvider。无需顶层 Expo 模块导入;适配器接受模块实例,因此即使未安装 Expo peer 依赖,CI 类型检查也能保持干净。

import * as SecureStore from 'expo-secure-store'
import * as WebBrowser from 'expo-web-browser'
import { XidProvider, createSecureStoreAdapter, createExpoWebBrowserAdapter } from '@xid-kit/expo'

const tokenCache = createSecureStoreAdapter({ secureStore: SecureStore })
const browser = createExpoWebBrowserAdapter({ webBrowser: WebBrowser })

export default function App() {
  return (
    <XidProvider
      publishableKey="pk_live_..."
      issuer="https://xid.dev"
      clientId="your_client_id"
      redirectUri="myapp://auth/callback"
      tokenCache={tokenCache}
      browser={browser}
    >
      <RootLayout />
    </XidProvider>
  )
}

登录与登出

import { useSignIn, useSignOut } from '@xid-kit/expo'
import { Button } from 'react-native'

function SignInScreen() {
  const { signIn, signInState } = useSignIn()
  return (
    <Button
      title={signInState.status === 'pending' ? 'Signing in...' : 'Sign In'}
      onPress={() => void signIn()}
    />
  )
}

function SignOutScreen() {
  const { signOut } = useSignOut()
  return <Button title="Sign Out" onPress={() => void signOut()} />
}

Expo Router 路由守卫

在布局组件中调用 useProtectedRoute。它从 useAuth 读取 isLoaded/isSignedIn,并在 useEffect 内调用 Expo Router 的 replace

import { useProtectedRoute } from '@xid-kit/expo'
import { useRouter, usePathname } from 'expo-router'

export default function RootLayout() {
  const router = useRouter()
  const pathname = usePathname()

  useProtectedRoute({
    signInRoute: '/sign-in',
    protectedRoute: '/(app)',
    pathname,
    replace: router.replace,
  })

  return <Slot />
}

SecureStore 密钥命名空间

使用 keyPrefix 为密钥添加自定义前缀命名空间。分隔符为 .(点号),在 expo-secure-store 允许的字符集范围内。

const tokenCache = createSecureStoreAdapter({
  secureStore: SecureStore,
  keyPrefix: 'myapp',
  // keys: 'myapp.xid.access_token', 'myapp.xid.refresh_token', etc.
})

导出的 API

导出 类型 用途
XidProvider 组件 重导出接受 tokenCache 和浏览器适配器的 @xid-kit/react-native XidProvider
createSecureStoreAdapter function 由 expo-secure-store 支持的 TokenCache 适配器;接受 secureStore 实例和可选的 keyPrefix
createExpoWebBrowserAdapter function 由 expo-web-browser 支持的 BrowserInterface 适配器
useSignIn hook 来自 @xid-kit/react-native 的重导出:signIn、handleRedirect、signInState
useSignOut hook 来自 @xid-kit/react-native 的重导出:signOut、signOutState
useProtectedRoute hook 读取 isLoaded/isSignedIn 并调用 Expo Router replace 进行路由保护

已知限制

  • useAuth().isSignedIn 反映的是 XidClient Web cookie 会话状态,token 交换后不会自动从本地 SecureStore token 填充。登录成功后请显式重新加载客户端状态。
  • 此包仅提供适配器和 Expo Router 集成。基础 React Native PKCE 流程请参见 @xid-kit/react-native
导航

输入内容以搜索...

使用方向键导航按 Enter 键选择按 Escape 键关闭