Asgardeo is an IDaaS platform that helps organizations simplify and secure their IAM processes. It offers a wide range of features, including SSO, social login, MFA, passwordless authentication, user management, and logging, making it a great option for organizations looking to simplify and secure their IAM processes.
React Native is an open-source cross-platform mobile development framework created by Meta Platforms, Inc. It is used to develop applications for Android, iOS, macOS, tvOS, Web, Windows, and UWP by enabling developers to use the React framework along with native platform capabilities.
In this guide, we will explore how to integrate Asgardeo into your React Native apps, using react-native-app-auth
, a well know authentication SDK for React Native apps.
We are going to build a super simple application that has login and logout capabilities. Our application will have two screens, one is public and the other one is private. Users will have to authenticate by proving their identity to access the private page. This protected page will also show the logged-in user's information.
The Official React Native Getting Started page contains the most up-todate information on how to setup the development environment and creating a new React Native project. Follow the steps outlined there, based on the operating system and your targeted mobile platform.
Once you are up and running with the new React Native project, come back to this guide to follow the next steps.
Stop the running metro server and run the following command in the project root to intall the required dependencies.
npm install react-native-app-auth rn-secure-storage react-navigation --save
As Asgardeo conforms to the standard identity management specifications, you can use any standard SDK/library that implements standard identity protocols to integrate Asgardeo with your applications. For this reason, we can use the standard react-native-app-auth
package to add Asgardeo auth to our React Native application.
react-navigation
is a navigation library for React Native, that allows you to easily navigate between screens in your app, with support for gestures, animations, and customizability. We will be using it to configure navigation in our mobile app.
After the sign-in is completed, we need to store the credentials received (eg: access token, id token, refresh token etc.) securely in the device itself. The rn-secure-storage
package provides that secure storage capability utilizing the underlying platform specific secure storage features.
💡 Tip
If you are unable to use rn-secure-storage
package, have a look at the other recommendations
To integrate Asgardeo with our mobile app, we first need to create an application on Asgardeo console and obtain app-specific credentials. Follow the comprehensive guide in the Asgardeo documentation to create an application.
We also need to have a user in our organization to log into our app using Asgardeo. Create a user in your Asgardeo organization by following these steps.
Once you created an application and a user, come back to this guide to follow the next steps.
To demonstrate the sign in with Asgardeo, we are building a simple app with two pages, home and dashboard. The home screen contains a button to initiate the sign in process, while the second screen has a Sign Out button. Let's first create the skeleton of two screens.
🗒️ Note
The styles and the imports have been excluded in some of the following code snippets for brevity.
Create src/views/HomeScreen.tsx
and add the following content.
export const HomeScreen = () => {
const signIn = () => {
// we are going to update this function in the next steps.
}
return (
<View>
<TouchableOpacity onPress={signIn}>
<Text>Sign In</Text>
</TouchableOpacity>
</View>
)
}
Create src/views/DashboardScreen.tsx
and add the following content.
export const DashboardScreen = () => {
const signOut = () => {
// we are going to update this function in the next steps.
}
return (
<View>
<TouchableOpacity onPress={signOut}>
<Text>Sign Out</Text>
</TouchableOpacity>
</View>
)
}
We will be updating the
signIn
andsignOut
functions in the next steps.
Let's use React Contexts to hold the user's authentication state in a way that's accessible by all views in our apps. Create a file src/contexts/UserContext.tsx
and add the following code.
import { createContext, Dispatch, SetStateAction } from 'react';
export const UserContext = createContext<{
isLoggedIn: boolean;
setIsLoggedIn: Dispatch<SetStateAction<boolean>>;
}>({
isLoggedIn: false,
setIsLoggedIn: (_isSignedIn: SetStateAction<boolean>) => null,
});
As the last step, let's define the navigation for these screens using the stack navigation available in react-navigation
package.
import React, { useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { UserContext } from './src/contexts/UserContext';
import { DashboardScreen } from './src/views/Dashboard';
import { HomeScreen } from './src/views/Home';
function App(): JSX.Element {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<UserContext.Provider value={{ isLoggedIn, setIsLoggedIn }}>
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
{isLoggedIn ? (
<Stack.Screen name="Dashboard" component={DashboardScreen} />
) : (
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
title: '',
headerShown: false,
}}
/>
)}
</Stack.Navigator>
</NavigationContainer>
</UserContext.Provider>
);
}
To integrate Asgardeo with our app, we need to specify some values that are unique to our Asgardeo organization. Create a file named src/config.ts
and add the following. Make sure to update the placeholder values with your own values.
You can obtain these values from the Quick Start section of the application you created in the Asgardeo console.
export const config = {
issuer: 'https://api.asgardeo.io/t/<your_org_name>/oauth2/token',
clientId: '<your_application_id>',
redirectUrl: 'myapp.auth://example',
scopes: ['openid', 'profile'],
postLogoutRedirectUrl: 'myapp.auth://example',
};
Here is a short description of each config value.
Config value | Description |
---|---|
issuer | API endpoint that issues tokens upon request. |
clientId | The Client ID of your OIDC app. |
redirectUrl | The URL to which the app redirects to after user login. |
scopes | The list of OIDC scopes that are used for requesting user information. The openid scope is mandatory to get the ID token. You can add other OIDC scopes such as profile and email. |
postLogoutRedirectUrl | The URL which the app redirects to after user logout |
We are using the authorize
function provided by the authentication library to make the sign in work. Open the src/views/HomeScreen.tsx
and update the signIn
function as follows.
import { authorize } from 'react-native-app-auth';
import { config } from '../config';
const signIn = () => {
try {
setIsLoading(true);
const result = await authorize(config);
RNSecureStorage.set('authorizeResponse', JSON.stringify(result), {
accessible: ACCESSIBLE.WHEN_UNLOCKED,
}).then(
_res => {
setIsLoggedIn(true);
},
err => {
throw err;
},
);
} catch (error) {
console.log(error);
setIsLoggedIn(false);
} finally {
setIsLoading(false);
}
}
Let's try to understand what's happening here.
In the very beginning of the signIn
function, we update loading state variable to true so that the sign in button text is updated to Loading...
until the browser is popped up. Then we call the authorize method from the react-native-app-auth
library to handle the whole sign in process. The library then handles the authentication flow internally and eventually returns the authentication response.
An example authentication response would be as follows.
{
"accessToken": "5da9101e-2572-3d8e-aeab-b6d8a114c324",
"accessTokenExpirationDate": "2023-07-30T13:42:56Z",
"authorizeAdditionalParameters": {
"session_state": "e1dd600650d0aadbbae70604f1e8623b4f4244514be535246db9fa809554..."
},
"idToken": "eyJ4NXQiOiJaVGMxWW1Nd09HSmtPREE1WXprNFl6Z3dZbVpoWkRJNE1tUXpObU0xWVRjelpUS...",
"refreshToken": "6dcf5331-4aa6-3eda-9537-c9acf57962af",
"scopes": ["openid", "profile"],
"tokenAdditionalParameters": {},
"tokenType": "Bearer"
}
Upon receiving the authentication response, we securely store it in the device for future use, and update the isLoggedIn
state variable value to true
, so that the private "Dashboard" screen is now visible.
Now we have added the sign in capability, let's continue to work on sign out functionality. Update the signOut
function in views/Dashboard.tsx
as follows.
const signOut = async () => {
if (!authResponse?.idToken) {
setIsLoggedIn(false);
return;
}
try {
await logout(config, {
idToken: authResponse?.idToken,
postLogoutRedirectUrl: config.postLogoutRedirectUrl,
});
RNSecureStorage.remove('authorizeResponse')
.then(_val => {
setIsLoggedIn(false);
})
.catch(err => {
throw err;
});
} catch (err) {
console.log(err);
}
};
Upon clicking on the sign out button, we remove the user credentials from device storage and redirect the user to the home screen.
In this tutorial, we looked into integrating Asgardeo with your React Native application, using the standard react-native-app-auth
package. I hope you found this guide useful. In case you faced any errors and have suggestions to improve the guide, please don't hesitate to
open an issue in the demo repository.
Until the next time, Thanks for reading!!!
© Pavindu Lakshan | 2024