Lesson 126 of 158 – React Native Login API
80%

React Native Login API

A login API allows a React Native application to send user credentials to a backend server and receive an authentication response. In this lesson, we will connect a React Native login screen with a PHP REST API using Axios and TypeScript.

Note: The mobile application should send the login credentials securely over HTTPS. The PHP server is responsible for validating the credentials and generating the authentication token.

1. What is a Login API?

A login API is an endpoint that receives login information and verifies the user.

POST /api/login.php

The API can receive an email and password and return a JWT or another authentication token after successful verification.

2. React Native Login Flow

Login Screen
     ↓
Email + Password
     ↓
Axios POST
     ↓
PHP Login API
     ↓
Verify Credentials
     ↓
Generate Token
     ↓
Login Response
     ↓
React Native
     ↓
Store Authentication State

3. Login Request Structure

The React Native application can send JSON data to the PHP API.

{
    "email": "student@example.com",
    "password": "123456"
}

The request should use the Content-Type: application/json header.

4. LoginRequest Interface

interface LoginRequest {
    email: string;
    password: string;
}

This interface describes the data sent from React Native to the API.

5. Login Response Interface

interface User {
    id: number;
    name: string;
    email: string;
    role: "admin" | "teacher" | "student";
}

interface LoginResponse {
    success: boolean;
    message: string;
    token: string;
    user: User;
}

6. Creating an Axios Instance

import axios from "axios";

const api = axios.create({
    baseURL: "https://example.com/api",
    headers: {
        "Content-Type": "application/json"
    }
});

An Axios instance provides a central place for API configuration.

7. Login Function

const login = async (
    data: LoginRequest
): Promise<LoginResponse> => {

    const response =
        await api.post<LoginResponse>(
            "/login.php",
            data
        );

    return response.data;
};

8. React Native Login State

const [email, setEmail] =
    useState("");

const [password, setPassword] =
    useState("");

const [loading, setLoading] =
    useState(false);

const [error, setError] =
    useState("");

9. Creating Login Data

const data: LoginRequest = {
    email: email,
    password: password
};

Because the object uses the LoginRequest interface, TypeScript can check the structure of the request.

10. Calling the Login API

const result =
    await login({
        email,
        password
    });

console.log(result);

The returned value follows the LoginResponse interface.

11. Checking Login Success

if (result.success) {

    console.log(
        "Login successful"
    );

} else {

    console.log(
        result.message
    );
}

12. Receiving the JWT Token

if (result.success) {

    const token =
        result.token;

    console.log(token);
}

The token can later be used for protected API requests.

13. Receiving User Information

if (result.success) {

    console.log(
        result.user.name
    );

    console.log(
        result.user.email
    );

    console.log(
        result.user.role
    );
}

14. Loading State During Login

const handleLogin = async () => {

    try {

        setLoading(true);
        setError("");

        const result =
            await login({
                email,
                password
            });

        console.log(result);

    } catch (error) {

        setError(
            "Unable to login"
        );

    } finally {

        setLoading(false);

    }
};

15. Handling Axios Errors

import axios from "axios";

try {

    await login({
        email,
        password
    });

} catch (error) {

    if (axios.isAxiosError(error)) {

        console.log(
            error.response?.data
        );

    }

}

16. Handling Invalid Credentials

The PHP API can return HTTP 401 when the credentials are invalid.

{
    "success": false,
    "message": "Invalid email or password"
}

The application should show a safe message to the user instead of exposing internal server information.

17. PHP Login API Request

PHP can read the JSON request body using php://input.

$input = json_decode(
    file_get_contents("php://input"),
    true
);

$email = trim($input["email"] ?? "");
$password = $input["password"] ?? "";

18. PHP Login Validation

if ($email === "" || $password === "") {

    http_response_code(422);

    echo json_encode([
        "success" => false,
        "message" => "Email and password are required"
    ]);

    exit;
}

Server-side validation is required even if the React Native screen already validates the form.

19. Finding the User in PHP

$stmt = $pdo->prepare(
    "SELECT id, name, email, password, role
     FROM users
     WHERE email = ?"
);

$stmt->execute([$email]);

$user = $stmt->fetch(PDO::FETCH_ASSOC);

A prepared statement helps prevent SQL injection.

20. Verifying the Password

if (!$user ||
    !password_verify(
        $password,
        $user["password"]
    )) {

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" => "Invalid email or password"
    ]);

    exit;
}

The server should store passwords as secure hashes, not plain text.

21. Creating the Login Response

$response = [
    "success" => true,
    "message" => "Login successful",
    "token" => $token,
    "user" => [
        "id" => (int)$user["id"],
        "name" => $user["name"],
        "email" => $user["email"],
        "role" => $user["role"]
    ]
];

echo json_encode($response);

22. Sending the JWT from React Native

const response =
    await api.get(
        "/profile.php",
        {
            headers: {
                Authorization:
                    `Bearer ${token}`
            }
        }
    );

The token received during login is sent with later protected requests.

23. Authentication State After Login

interface AuthState {
    token: string | null;
    user: User | null;
    isAuthenticated: boolean;
}

setAuth({
    token: result.token,
    user: result.user,
    isAuthenticated: true
});

24. Navigating After Login

After successful authentication, the application can navigate to the appropriate protected screen.

if (result.success) {

    setAuth({
        token: result.token,
        user: result.user,
        isAuthenticated: true
    });

    navigation.navigate(
        "Home"
    );
}

Navigation is only a UI decision; the server must still protect API endpoints.

25. Complete Login Service

interface LoginRequest {
    email: string;
    password: string;
}

interface User {
    id: number;
    name: string;
    email: string;
    role: "admin" | "teacher" | "student";
}

interface LoginResponse {
    success: boolean;
    message: string;
    token: string;
    user: User;
}

export const login =
    async (
        data: LoginRequest
    ): Promise<LoginResponse> => {

    const response =
        await api.post<LoginResponse>(
            "/login.php",
            data
        );

    return response.data;
};

26. Complete Login Handler

const handleLogin = async () => {

    if (!email || !password) {

        setError(
            "Enter email and password"
        );

        return;
    }

    try {

        setLoading(true);
        setError("");

        const result =
            await login({
                email,
                password
            });

        if (result.success) {

            setAuth({
                token: result.token,
                user: result.user,
                isAuthenticated: true
            });

            navigation.navigate(
                "Home"
            );

        } else {

            setError(
                result.message
            );
        }

    } catch (error) {

        setError(
            "Login request failed"
        );

    } finally {

        setLoading(false);

    }
};

27. Login Screen Structure

<TextInput
    placeholder="Email"
    value={email}
    onChangeText={setEmail}
/>

<TextInput
    placeholder="Password"
    secureTextEntry
    value={password}
    onChangeText={setPassword}
/>

<Button
    title="Login"
    onPress={handleLogin}
/>

The form collects the credentials and sends them to the login service.

28. Complete React Native Login Example

const handleLogin = async () => {

    try {

        setLoading(true);
        setError("");

        const data: LoginRequest = {
            email,
            password
        };

        const result =
            await login(data);

        if (result.success) {

            console.log(
                "User:",
                result.user.name
            );

            console.log(
                "Token:",
                result.token
            );

            setAuth({
                token: result.token,
                user: result.user,
                isAuthenticated: true
            });

        } else {

            setError(
                result.message
            );
        }

    } catch (error) {

        setError(
            "Unable to connect to server"
        );

    } finally {

        setLoading(false);

    }
};

29. Complete Login Architecture

React Native
     │
     │ LoginRequest
     ↓
Axios
     │
     │ POST /login.php
     ↓
PHP REST API
     │
     ├── Validate Input
     ├── Find User
     ├── Verify Password
     └── Create JWT
     │
     ↓
LoginResponse
     │
     ├── success
     ├── message
     ├── token
     └── user
     │
     ↓
React Native AuthState
     │
     ↓
Protected Screens

30. Complete Login API Flow

1. User enters email and password
2. React Native validates the form
3. Axios sends POST request
4. PHP reads JSON request
5. PHP validates input
6. PHP finds the user
7. PHP verifies password hash
8. PHP creates JWT/token
9. PHP returns LoginResponse
10. React Native updates AuthState
11. Token is used for protected APIs
12. PHP verifies token on protected requests

This is the basic authentication flow used by a React Native application communicating with a PHP REST API. TypeScript interfaces make the request and response structures predictable while the server remains responsible for securely authenticating and authorizing the user.

📌 Key Points

  • A React Native login screen sends credentials to a login API.
  • Axios can send the login request to a PHP REST API.
  • TypeScript interfaces define LoginRequest and LoginResponse.
  • The PHP API should validate the request on the server.
  • Passwords should be verified using secure password hashes.
  • A successful login can return a JWT or authentication token.
  • The token can be sent using the Authorization Bearer header.
  • HTTP 401 can be used for invalid authentication.
  • Authentication state can contain the token and authenticated user.
  • Protected API endpoints must verify authentication on the server.

🧠 Quick Quiz

Question: Which HTTP method is normally used to send login credentials to a login API?