How to Secure Screens in a React Native Expo App Using Custom Email and Password Authentication with TypeScript

·3 min read
Share on
Securing Screens in a React Native Expo App Using Custom Email and Password Authentication with TypeScript

In this tutorial, we’ll go through a simple way to secure screens in a React Native app built with Expo, using custom email and password authentication. We'll be using TypeScript to ensure type safety and help avoid common bugs. By the end of this guide, you'll have a basic app with secure screens that only authenticated users can access.

Prerequisites

  • Basic knowledge of React Native and Expo.
  • Node.js installed on your machine.
  • Expo CLI installed globally (npm install -g expo-cli).

Step 1: Setting Up the Expo Project

1. Create a New Expo Project:

npx create-expo-app my-secure-app --template

2. Navigate to Your Project Directory:

cd my-secure-app

3. Install Dependencies: Since we will use React Navigation for routing and securing screens, let's install it along with necessary dependencies:

npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context

If you're using the Expo Router (newer navigation system):

npm install expo-router

Step 2: Creating the Authentication Logic

We'll create a simple mock authentication mechanism for demonstration purposes. This example will use hardcoded credentials, but in a real-world scenario, you would connect this to a backend service.

1. Create an AuthContext: We'll use the React Context API to manage authentication state globally.

  • Create a file named AuthContext.tsx in the contexts folder:
mkdir contexts
touch contexts/AuthContext.tsx
  • Add the following code:
// contexts/AuthContext.tsx
import React, { createContext, useState, ReactNode } from 'react';

type AuthContextType = {
  isAuthenticated: boolean;
  login: (email: string, password: string) => boolean;
  logout: () => void;
};

export const AuthContext = createContext<AuthContextType>({
  isAuthenticated: false,
  login: () => false,
  logout: () => {},
});

export const AuthProvider = ({ children }: { children: ReactNode }) => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  const login = (email: string, password: string) => {
    // Replace this with your authentication logic
    if (email === 'user@example.com' && password === 'password123') {
      setIsAuthenticated(true);
      return true;
    }
    return false;
  };

  const logout = () => {
    setIsAuthenticated(false);
  };

  return (
    <AuthContext.Provider value={{ isAuthenticated, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

Step 3: Creating the Authentication Screens

1. Create Login and Secure Screen Components:

  • Create a folder named screens:
mkdir screens
touch screens/LoginScreen.tsx screens/SecureScreen.tsx
  • Add the LoginScreen component:
// screens/LoginScreen.tsx
import React, { useState, useContext } from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';
import { AuthContext } from '../contexts/AuthContext';

const LoginScreen = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const { login } = useContext(AuthContext);

  const handleLogin = () => {
    if (!login(email, password)) {
      alert('Invalid credentials');
    }
  };

  return (
    <View style={styles.container}>
      <Text>Email:</Text>
      <TextInput
        style={styles.input}
        value={email}
        onChangeText={setEmail}
        autoCapitalize="none"
      />
      <Text>Password:</Text>
      <TextInput
        style={styles.input}
        value={password}
        onChangeText={setPassword}
        secureTextEntry
      />
      <Button title="Login" onPress={handleLogin} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 16,
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 12,
    paddingHorizontal: 8,
  },
});

export default LoginScreen;
  • Add the SecureScreen component:
// screens/SecureScreen.tsx
import React, { useContext } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { AuthContext } from '../contexts/AuthContext';

const SecureScreen = () => {
  const { logout } = useContext(AuthContext);

  return (
    <View style={styles.container}>
      <Text>Welcome to the secure screen!</Text>
      <Button title="Logout" onPress={logout} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default SecureScreen;

Step 4: Setting Up Navigation and Securing Screens

1. Create the App Router:

  • Modify App.tsx:
// App.tsx
import React, { useContext } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { AuthProvider, AuthContext } from './contexts/AuthContext';
import LoginScreen from './screens/LoginScreen';
import SecureScreen from './screens/SecureScreen';

const Stack = createNativeStackNavigator();

const App = () => {
  return (
    <AuthProvider>
      <NavigationContainer>
        <AppNavigator />
      </NavigationContainer>
    </AuthProvider>
  );
};

const AppNavigator = () => {
  const { isAuthenticated } = useContext(AuthContext);

  return (
    <Stack.Navigator>
      {isAuthenticated ? (
        <Stack.Screen name="Secure" component={SecureScreen} />
      ) : (
        <Stack.Screen name="Login" component={LoginScreen} />
      )}
    </Stack.Navigator>
  );
};

export default App;

Step 5: Testing the App

1. Run the App:

npx expo start

2. Open the app in an emulator or on your physical device.

3. Enter the email user@example.com and password password123. If successful, you'll be redirected to the secure screen.

Conclusion

Congratulations! You've built a simple email and password authentication system in a React Native Expo app using TypeScript. This example uses basic authentication logic, but in a real-world scenario, you would connect this to an authentication backend service.

This is a foundation upon which you can build more complex and secure authentication mechanisms, such as integrating with Firebase, Auth0, or your custom backend API.

Further Reading

Tags

React Native authenticationExpo app routersecure screens in React NativeTypeScript authenticationReact Native with Expocustom email password authenticationsecure React Native screensReact Native TypeScript guideExpo router authenticationReact Native security

Amarjeet

Amarjeet

Tech enthusiast and blogger, simplifying the latest gadgets, software, and digital trends. Making tech accessible, one post at a time.

Share on
Copyright © 2025 LatestLY.in.