On this page
This tutorial shows how to run a code example that implements mobile OpenID Connect in a React Native App using the Hypermedia Authentication API (HAAPI). See also the API Driven Demo Client tutorial for an introductory guide to HAAPI that runs a simple web client.
The code example uses the React Native HAAPI Module, which uses Kotlin and Swift to integrate with the following lower level HAAPI SDKs and provide an interface that React Native apps can easily consume.
Application Code Overview
To view the application code, clone the GitHub link at the top of this page. The example application produces two built apps for Android and iOS and uses configuration.android.jsx
and configuration.ios.jsx
files for each platform, since the underlying HAAPI SDKs have environment-specific configuration requirements. View the module documentation to understand all of the possible configuration settings that you can override.
const HaapiConfiguration = {"clientId": "haapi-android-client","keyStoreAlias": "haapi-react-native","baseUri": "https://login.example.com","tokenEndpointUri": "https://login.example.com/oauth/v2/oauth-token","authorizationEndpointUri": "https://login.example.com/oauth/v2/oauth-authorize","revocationEndpointUri": "https://login.example.com/oauth/v2/oauth-revoke","validateTlsCertificate": false,"scope": "openid profile","appRedirect": "haapi://callback"};const HaapiConfiguration = {"clientId": "haapi-ios-client","baseUri": "https://login.example.com","tokenEndpointUri": "https://login.example.com/oauth/v2/oauth-token","authorizationEndpointUri": "https://login.example.com/oauth/v2/oauth-authorize","revocationEndpointUri": "https://login.example.com/oauth/v2/oauth-revoke","validateTlsCertificate": false,"scope": "openid profile","appRedirect": "app:start"}
When the application starts it asks the module to load the configuration and apply other defaults.
HaapiModule.load(haapiConfiguation)
In the App.jsx
module the app creates a React Context to make its HAAPI state available to views. It also creates a HaapiProcessor
view that manages API driven logins. The HaapiProcessor
subscribes to events that the React Native HAAPI module emits.
useEffect(() => {listeners.push(addEventListener('AuthenticationStep', event => processAuthenticationStep(event)),addEventListener('AuthenticationSelectorStep', event => processAuthenticationStep(event)),addEventListener('PollingStep', event => processAuthenticationStep(event)),addEventListener('ContinueSameStep', event => processAuthenticationStep(event)),addEventListener('TokenResponse', event => processTokenResponse)),addEventListener('TokenResponseError', processTokenResponseError)),addEventListener('HaapiError', haapiError)),);return () => {console.debug('Removing all listeners in HaapiProcessor');listeners.forEach(listener => removeEventListener(listener));};}, []);
To initiate a user login, the application's WelcomeView
makes a call to Haapi.startLogin
. The application then receives Hypermedia Authentication API responses that contain actions that the application must handle. Study the components/actions
folder to understand the action logic.
const StepActions = (props) => {const {actions, haapiResponse} = props;let actionShowMessages = false;let actionShowLinks = false;const actionComponents = actions.map(action => {switch (action.kind) {case 'poll':return <PollingAction poll={() => Haapi.submitAction(action)} key={'polling'} />;case 'redirect':Haapi.followLink(action.model);return nullcase 'authenticator-selector':return <AuthenticatorSelectorAction action={action}key={'authenticator-selector'} />}});}
In particular, the actions create runtime user interface elements from API responses, whose appearance you can customize. The following screenshot shows the code example's default rendering of a username and password screen.

The example application uses only basic presentation, but mobile developers have full control over the layout and theming of application screens. Therefore you could update the example application's basic views to create your preferred login user experience.
Deploy Backend Infrastructure
Before you can run the example application you must deploy the Curity Identity Server. When getting started, use the automated deployment in the GitHub repository. First, copy a license.json
file for the Curity Identity Server to the root folder of the project. Then, study the README instructions to understand options and finally run the deployment, which automates the configuration settings from the following tutorials:
- Android Client Setup for the Hypermedia Authentication API
- iOS Client Setup for the Hypermedia Authentication API
You can run the deployment in various ways. One productive option is to use ngrok mobile setup so that the Curity Identity Server runs at a trusted internet HTTPS URL. You can then easily view all HAAPI responses using a local inspect URL such as http://127.0.0.1:4040/inspect/http
. The following example HAAPI response results in the app rendering a username and password login screen.
{"links": [{"href": "/authn/authentication/HtmlForm/forgot-password","rel": "forgot-password","title": "Forgot your password?"},{"href": "/authn/authentication/HtmlForm/forgot-account-id","rel": "forgot-account-id","title": "Forgot your username?"},{"href": "/authn/registration/HtmlForm","rel": "register-create","title": "Create account"}],"metadata": {"viewName": "authenticator/html-form/authenticate/get"},"type": "authentication-step","actions": [{"template": "form","kind": "login","title": "Login","model": {"href": "/authn/authentication/HtmlForm","method": "POST","type": "application/x-www-form-urlencoded","actionTitle": "Login","fields": [{"name": "userName","type": "username","label": "Username"},{"name": "password","type": "password","label": "Password"}]}}]}
Run the Application
To run the React Native application, use standard React Native commands. First, use the following command to run the Metro bundler which reloads the application after code changes.
npm start
Then run an emulator for your platform from another terminal window for your preferred mobile platform.
npm run androidnpm run ios
The GitHub repository's README file explains details on how to sign in with a pre-shipped user account. Start with the HTML Form authenticator to sign in with a pre-shipped user account named demouser
and a password of Password1
.
Test Native Passkey Logins
A HAAPI application can use any built-in or custom user authentication method that you configure in the Curity Identity Server. You can even use the plugin system of the Curity Identity server to develop completely custom authenticators that return HAAPI responses to the React Native app.
The example deployment enables testing of Android and iOS native passkeys logins. The deployment configures associated domains using hosted assets documents. To test this option, redeploy the Curity Identity Server using ngrok so that the React Native application can call the Curity Identity Server at a trusted HTTPS internet URL.
To test this option, use ngrok to expose the Curity Identity Server at a trusted HTTPS internet URL. Register a passkey for the demouser
account. When prompted, use the HTML Form authenticator as the passkeys registration authenticator. Then, on all subsequent logins, sign in with a passkey.


The Configure Native Passkeys for Mobile Logins explains more about the technical setup to enable logins with passkeys.
Call APIs with Tokens
Once user authentication completes, the application receives a set of OAuth tokens in its TokenResponse
event handler and can call APIs. The AuthenticatedView
shows how to receive and work with tokens and how to refresh access tokens when they expire.

Test Reliability
As the application runs, the terminal running the Metro bundler shows debug output from the HAAPI SDKs. These statements can help to understand flows or troubleshoot when required.
DEBUG Creating view with messages: [] and links: [{"rel":"forgot-password","title":"Forgot your password?","href":"/authn/authentication/HtmlForm/forgot-password"},{"rel":"forgot-account-id","title":"Forgot your username?","href":"/authn/authentication/HtmlForm/forgot-account-id"},{"rel":"register-create","title":"Create account","href":"/authn/registration/HtmlForm"}]DEBUG Submitting action: {"model":{"href":"/authn/authentication/HtmlForm","method":"POST","errorActions":[],"type":"application/x-www-form-urlencoded","fields":[{"label":"Username","name":"userName"},{"label":"Password","name":"password"}],"continueActions":[],"actionTitle":"Login"},"title":"Login","kind":"login"}
Some mobile flows can use considerable infrastructure so you should understand how to troubleshoot. During development, make sure that you test with invalid configuration settings to ensure that your application handles them in a resilient way. Handle the HaapiError
event and other failure events that may be relevant to your particular authentication flows.
addEventListener('HaapiError', event => {reportError(event.error, event.error_description);});
Conclusion
A React Native client can use any authentication method(s) configured in the Curity Identity Server and then receive access tokens once login completes, to enable API access. With the Hypermedia Authentication API, applications use a pure native login user experience. Mobile developers can also take full control over the look and feel, without needing to rely on a central identity team to deploy changes to the Curity Identity Server.
Join our Newsletter
Get the latest on identity management, API Security and authentication straight to your inbox.
Start Free Trial
Try the Curity Identity Server for Free. Get up and running in 10 minutes.
Start Free Trial