Build Expo (React Native) authentication with Logto

Learn how to build a user authentication flow with Expo (React Native) by integrating Logto SDK.
Gao
GaoFounder
February 28, 20243 min read
Build Expo (React Native) authentication with Logto

Get started

Introduction

  • Logto is an open-source Auth0 alternative for building identity infrastructures. It supports various sign-in methods, including username, email, phone number, and popular social sign-ins like Google and GitHub.
  • Expo (React Native) is an ecosystem of tools that help you create universal native apps with React that run on Android, iOS, and the web.

In this tutorial, we will show you how to build a user authentication flow with Expo (React Native) by integrating Logto SDK. The tutorial uses TypeScript as the programming language.

Prerequisites

Before you begin, ensure you have the following:

  • A Logto account. If you don't have one, you can sign up for free.
  • An Expo (React Native) development environment and a project.

Create a Logto application

To get started, create a Logto application with the "Native" type. Follow these steps to create a Logto application:

  1. Sign in to the Logto Console.
  2. In the left navigation bar, click on Applications.
  3. Click on Create application.
  4. In the opened page, find the "Native" section and locate the "Expo (React Native)" card.
  5. Click on Start building, and input the name of your application.
  6. Click on Create.

Then you should see an interactive tutorial that guides you through the process of integrating Logto SDK with your Expo (React Native) application. The following content can be a reference for future use.

Integrate with Logto SDK

Installation

Install Logto SDK and peer dependencies via your favorite package manager:

# or pnpm, yarn, etc.
npm i @logto/rn
npm i expo-crypto expo-secure-store expo-web-browser @react-native-async-storage/async-storage

The @logto/rn package is the SDK for Logto. The remaining packages are its peer dependencies. They couldn't be listed as direct dependencies because the Expo CLI requires that all dependencies for native modules be installed directly within the root project's package.json.

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

Init Logto provider

Import and use LogtoProvider to provide a Logto context:

import { LogtoProvider, LogtoConfig } from '@logto/rn';

const config: LogtoConfig = {
  endpoint: '<your-logto-endpoint>',
  appId: '<your-application-id>',
};

const App = () => (
  <LogtoProvider config={config}>
    <YourAppContent />
  </LogtoProvider>
);

Implement sign-in and sign-out

Switch to the application details page of Logto Console. Add a native redirect URI (for example, io.logto://callback), then click "Save".

  • For iOS, the redirect URI scheme does not really matter since the ASWebAuthenticationSession class will listen to the redirect URI regardless of if it's registered.

  • For Android, the redirect URI scheme must be filled in Expo's app.json file, for example:

    {
      "expo": {
        "scheme": "io.logto"
      }
    }

Now back to your app, you can use useLogto hook to sign in and sign out:

import { useLogto } from '@logto/rn';
import { Button } from 'react-native';

const Content = () => {
  const { signIn, signOut, isAuthenticated } = useLogto();

  return (
    <div>
      {isAuthenticated ? (
        <Button title="Sign out" onPress={async () => signOut()} />
      ) : (
        // Replace the redirect URI with your own
        <Button title="Sign in" onPress={async () => signIn('io.logto://callback')} />
      )}
    </div>
  );
};

Display user information

To display the user's information, you can use the getIdTokenClaims() method:

import { useLogto } from '@logto/rn';
import { Button, Text } from 'react-native';

const Content = () => {
  const { getIdTokenClaims, isAuthenticated } = useLogto();
  const [user, setUser] = useState(null);

  useEffect(() => {
    if (isAuthenticated) {
      getIdTokenClaims().then((claims) => {
        setUser(claims);
      });
    }
  }, [isAuthenticated]);

  return (
    <div>
      {isAuthenticated ? (
        <>
          <Text>{user?.name}</Text>
          <Text>{user?.email}</Text>
          <Button title="Sign out" onPress={async () => signOut()} />
        </>
      ) : (
        <Button title="Sign in" onPress={async () => signIn('io.logto://callback')} />
      )}
    </div>
  );
};

Checkpoint: Run the application

Now you can run the application and try to sign-in/sign-out with Logto:

  1. Open the application in your browser, you should see the "Sign in" button.
  2. Click the "Sign in" button, and you should be redirected to the Logto sign-in page.
  3. After you have signed in, you should be redirected back to the application, and you should see the user data and the "Sign out" button.
  4. Click the "Sign out" button, and you should be redirected to the Logto sign-out page, and then redirected back to the application with an unsigned-in state.

If you encounter any issues during the integration, please don't hesitate to join our Discord server to chat with the community and the Logto team!

Further readings