Skip to content

@xid-kit/react-native

React Native provider and hooks for Hosted Auth redirect, PKCE S256, deep-link callback, and secure token storage adapters.

Status

Registry status: UNPUBLISHED. Install this SDK only from the repository source checkout; do not use an external package registry.

Package status is Current package. It implements a native token-session contract: Hosted Auth redirect with PKCE S256, state and nonce validation on the deep-link callback, verified ID token claims, authorization code exchange, and secure session persistence through an injected storage adapter.

A real IdP round-trip on production infrastructure is still pending manual verification. This page documents implemented behavior; it is not a readiness claim.

Provider setup

Inject a TokenCache (platform secure storage) and a BrowserInterface (in-app browser) into XidProvider. The SDK does not hard-bind any native module; Expo apps can use the ready-made adapters from @xid-kit/expo.

import { XidProvider } from '@xid-kit/react-native'
import type { BrowserInterface, TokenCache } from '@xid-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('xid', 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 (
    <XidProvider
      issuer="https://xid.dev"
      clientId="your_client_id"
      redirectUri="myapp://auth/callback"
      tokenCache={tokenCache}
      browser={browser}
    >
      <RootNavigator />
    </XidProvider>
  )
}

Sign in

signIn() builds the PKCE S256 authorize URL, stores the verifier, OAuth state, and nonce in the token cache, opens the browser adapter, and exchanges the returned code for a verified native session. Browser failure, state mismatch, ID token verification, and token exchange errors surface as signInState.status === 'error'.

import { useSignIn } from '@xid-kit/react-native'

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

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

When the browser adapter cannot capture the redirect itself, register the redirect URI scheme in your app manifest and forward the deep link to handleRedirect(url). It validates and consumes the OAuth state, verifier, and nonce, exchanges the code, verifies the ID token, and stores the native session.

import { useSignIn } from '@xid-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
}

Exported API

Export Kind Purpose
XidProvider component Provides a native token-session context using tokenCache, browser, issuer, clientId, redirectUri, scopes, and optional fetcher
useSignIn hook signIn(options?) runs the full redirect flow; handleRedirect(url) processes a deep-link callback; signInState reports idle, pending, complete, cancelled, or error
useSignOut hook signOut() clears the local session and legacy credentials; signOutState reports progress or storage failures; no revoke request is sent
useXidRnContext hook Raw adapter context (advanced use and testing)
exchangeCodeForTokens function Low-level POST to the token endpoint with grant_type authorization_code and the PKCE verifier; returns a TokenSet
saveTokenSet / clearTokenSet functions Persist or remove the token set in the TokenCache adapter
TOKEN_KEYS as const object TokenCache key names for the current session envelope and pending PKCE, state, and nonce records; legacy token keys are cleanup-only
createPkceVerifier / createPkceChallenge functions PKCE S256 utilities delegated to @xid-kit/protocol (Web Crypto)
createRandomString / base64UrlEncode functions URL-safe random string for OAuth state; base64url encoding helper

Native hooks and controls

Unlike @xid-kit/react, this package uses its own native token context. It exports useAuth, useUser, useSession, useSignIn, useSignOut, useXidRnContext, SignedIn, SignedOut, XidLoaded, XidLoading, exchangeCodeForTokens, saveTokenSet, readTokenSet, and clearTokenSet; it does not import or re-export the React web SDK.

Types

Type Description
XidProviderProps Native provider props: children, tokenCache, browser, issuer, clientId, redirectUri, optional scopes (default openid, profile, email), and optional fetcher
TokenCache Storage adapter contract: getToken, saveToken, deleteToken (all async)
BrowserInterface openAuthSession(url, redirectUri) resolving to a BrowserResult
BrowserResult Union of success (with callback URL), cancel, and dismiss
SignInOptions Per-call overrides for signIn: redirectUri, scopes
SignInState / SignOutState Discriminated status unions returned by the hooks
UseSignInReturn / UseSignOutReturn Hook return shapes: actions plus state
TokenExchangeInput / TokenSet Input and result of exchangeCodeForTokens: accessToken, idToken, expiresIn, and verified ID token claims
XidRnContextValue Adapter context shape returned by useXidRnContext

Known limitations

  • The SDK has no DPoP sender binding, rejects offline_access, and requires a new authorization flow after the access token expires.
  • useAuth().isSignedIn reflects a locally stored session only after ID token verification; it does not read a web cookie session.
  • Organization context is not populated from stored tokens yet.

Security

  • Authorization code with PKCE S256 only. No implicit or password grant.
  • Public clients never store client secrets.
  • PKCE verifier and OAuth state live in the injected secure storage adapter and are deleted after the code exchange.
  • signOut clears the local session and legacy credentials without a refresh or revoke request; storage failures surface in signOutState.
Navigation

Type to search...

Use arrow keys to navigateEnter to selectEscape to close