OIDC authentication for React Native with shared core and ready-to-use implementations for Expo and Bare React Native.
react-native-oidc-auth-core: framework-agnostic core with login, logout, refresh, and secure token storage contracts.react-native-oidc-auth-expo: Expo implementation using expo-auth-session and expo-secure-store.react-native-oidc-auth: Bare React Native implementation using react-native-app-auth and react-native-keychain.
While integrating a React Native app with Keycloak, the only available library I found (react-native-keycloak) was unmaintained. I found other OIDC auth clients that worked well, such as:
- react-native-app-auth
- expo-auth-session
However, both lacked:
- Automatic token refresh
- Secure token storage integration
This library fills those gaps and provides an implementation for Expo and Bare React Native.
- Login, logout, and token refresh
- Secure token storage
- Automatic token refresh
- Implementation for Expo and Bare RN
- Optional registration flow (Keycloak-tested)
Expo apps:
npm i react-native-oidc-auth-expoBare React Native apps:
npm i react-native-oidc-authConfigure your OIDC provider:
import { createOidcAuth, type OidcConfiguration, setTracingLogger } from 'react-native-oidc-auth'; // or react-native-oidc-auth-expo
const issuer = `${OIDC_URL}/realms/${OIDC_REALM}`;
const config: OidcConfiguration = {
issuer,
clientId: CLIENT_ID ?? '',
redirectUrl: REDIRECT_URI ?? '',
postLogoutRedirectUrl: REDIRECT_URI ?? '',
scopes: ['openid', 'profile'],
// Bare RN only:
dangerouslyAllowInsecureHttpRequests: __DEV__,
};
// Optional: Configure tracing
setTracingLogger(tracingLog);
export const oidcAuth = createOidcAuth(config);Wrap your app with the provider:
import React from 'react';
import { OidcAuthProvider } from 'react-native-oidc-auth'; // or react-native-oidc-auth-expo
import { Main } from './components/main';
import { oidcAuth } from './lib/oidc-auth';
export default function App() {
return (
<OidcAuthProvider instance={oidcAuth}>
<Main />
</OidcAuthProvider>
);
}Use the hook to access auth state and actions:
import React from 'react';
import { View, Text, Button } from 'react-native';
import { useOidcAuth } from 'react-native-oidc-auth'; // or react-native-oidc-auth-expo
export const Main: React.FC = () => {
const { isAuthenticated, user, login, logout } = useOidcAuth();
return (
<View>
{isAuthenticated ? (
<>
<Text>Home</Text>
<Text>Email: {user?.email}</Text>
<Button onPress={logout} title="Logout" />
</>
) : (
<>
<Text>Login</Text>
<Button onPress={login} title="Login" />
</>
)}
</View>
);
};You can depend on react-native-oidc-auth-core to build your own adapter for alternative auth/secure storage libraries.
This feature does not perform dynamic client registration.
Instead, it allows you to directly display the registration page and retrieve the token after completing the registration flow (tested with Keycloak only).
- Set the registration endpoint:
const config: OidcConfiguration = {
// ...
registrationPageEndpoint: `${issuer}/protocol/openid-connect/registrations`,
};- Call register from your UI:
import React from "react";
import { View, Text, Button } from "react-native";
import { useOidcAuth } from "react-native-oidc-auth";
export const Main: React.FC = () => {
const { isAuthenticated, login, register } = useOidcAuth();
return (
<View>
{!isAuthenticated ? (
<>
<Text>Login</Text>
<Button onPress={login} title="Login" />
<Button onPress={register} title="Register" />
</>
) : (
<Text>Home</Text>
)}
</View>
);
};Keycloak flow overview:
- User is redirected to the registration page.
- After submitting, Keycloak sends a verification email.
- The email link returns to the app; the token is stored, and the user is authenticated.
See examples/react-native and examples/expo for demo apps.
The logic in the core library is adapted from Keycloak JS.
MIT