Fingerprint authentication in expo

Fingerprint authentication in expo

We have seen apps that use Biometric Prompts as a layer of security in the application.

Finger print

Implementing this in expo is really easy. You can find the complete code for this at this link.

Screens

This app will have two screens.

  • Home
  • Start

To give a brief, the Start screen will have the authentication button. When the user clicks on this button, the app will ask for the biometric prompt. If the user successfully authenticates, the app will navigate to the Home screen.

App.js

App.js is used to setup our stack navigator between the two screens Home and Start.

<NavigationContainer>
    <Stack.Navigator initialRouteName="Start">
        <Stack.Screen
            name="Start"
            component={Start}
            options={{ headerShown: false }}
        />
        <Stack.Screen name="Home" component={HomeScreen} />
    </Stack.Navigator>
</NavigationContainer>

Start.js

We will import the expo-local-authentication package . This package allows you to use faceID and TouchID in IOS devices and Biometric Prompt in Android devices.

import * as LocalAuthentication from "expo-local-authentication";

We create two states to check if the device supports biometric and if any fingerprint is saved in the device.

const [isBiometricSupported, setIsBiometricSupported] = useState(false);
const [fingerprint, setFingerprint] = useState(false);

We use the hasHardwareAsync method to check if the device supports biometric authentication. isEnrolledAsync checks if any fingerprint is saved in the device.

useEffect(() => {
    (async () => {
        const compatible = await LocalAuthentication.hasHardwareAsync();
        setIsBiometricSupported(compatible);
        const enroll = await LocalAuthentication.isEnrolledAsync();
        if (enroll) {
            setFingerprint(true);
        }
    })();
}, []);

We create a simple page with a button to authenticate the user. In case Biometric is not supported or doesn't have any registered fingerprints, we show a message.

<View style={styles.start}>
    <View style={{ justifyContent: "center", flex: 1, alignItems: "center" }}>
        {isBiometricSupported && fingerprint ? (
            <TouchableOpacity onPress={handle}>
                <Text style={styles.button}>Go to home</Text>
            </TouchableOpacity>
        ) : (
            <View>
                <Text>fingerprint not supported/ allocated</Text>
            </View>
        )}
    </View>
</View>

handle is a function that will authenticate the user.

const handle = async () => {
    try {
        const biometricAuth = await LocalAuthentication.authenticateAsync({
            promptMessage: "Login with Biometrics",
            disableDeviceFallback: true,
            cancelLabel: "Cancel",
        });
        if (biometricAuth.success) {
            navigation.replace("Home");
        }
    } catch (error) {
        console.log(error);
    }
};

aunthenticateAsync is a method that will authenticate the user. we pass the following parameters.

  • promptMessage: This is the message that will be displayed to the user.
  • disableDeviceFallback: This is a boolean value that will disable the fallback option. When we fail to authenticate with fingerprint for several attempts the device falls back to the default password if disableDeviceFallback is set to false.
  • cancelLabel: This is the label for the cancel button.

If the authentication is successful we navigate to the Home screen. navigation.replace is a method we use so that the user doesn't see a back button to go back to the Start screen. unlike navigation.navigate which will push the new screen on top of the current screen, navigation.replace will replace the current screen with the new screen.

Did you find this article valuable?

Support Chinmay Mhatre by becoming a sponsor. Any amount is appreciated!