Lesson 157 of 158 – Project Authentication Flow
99%

Project Authentication Flow

In this lesson, we will connect all authentication parts of our Student Management mobile application.

We will understand how registration, login, JWT authentication, AsyncStorage, Axios, protected APIs, Auth Context, navigation, persistent login, and logout work together.

Project Goal: Understand and implement the complete authentication flow between React Native, TypeScript, Axios, JWT, PHP, and MySQL.

1. Complete Authentication Flow

Registration
      ↓
Login
      ↓
PHP API
      ↓
Verify Password
      ↓
Create JWT
      ↓
React Native
      ↓
Store JWT
      ↓
Auth Context
      ↓
Protected Navigation
      ↓
Protected API
      ↓
JWT Verification
      ↓
User Data
      ↓
Logout

2. Authentication vs Authorization

Authentication answers:

"Who is the user?"

Authorization answers:

"What is this user allowed to do?"

Authentication
→ Login
→ JWT
→ User identity

Authorization
→ Role
→ Permissions
→ Protected actions

3. Registration Flow

Registration Screen
        ↓
Name + Email + Password
        ↓
POST /register.php
        ↓
PHP Validation
        ↓
password_hash()
        ↓
MySQL INSERT
        ↓
HTTP 201
        ↓
Registration Successful

Registration creates the user's account. Login is performed separately to obtain the authentication token.

4. Login Flow

Login Screen
      ↓
Email + Password
      ↓
POST /login.php
      ↓
Find User
      ↓
password_verify()
      ↓
Create JWT
      ↓
Return Token
      ↓
React Native

5. Login Request Interface

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

TypeScript ensures that the login request contains the expected fields.

6. Login Response Interface

interface User {
    id: number;
    name: string;
    email: string;
    role: string;
}

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

7. Axios Login Request

const response =
    await api.post<LoginResponse>(
        "/login.php",
        {
            email,
            password
        }
    );

const token =
    response.data.token;

8. JWT Token

After successful login, the PHP API creates a JSON Web Token.

JWT
├── Header
├── Payload
└── Signature

The token represents the authenticated session information required by the protected API.

9. Store JWT with AsyncStorage

import AsyncStorage
from "@react-native-async-storage/async-storage";

await AsyncStorage.setItem(
    "auth_token",
    response.data.token
);

The token can be stored locally so that authentication can continue when the application is reopened.

10. Store User Information

await AsyncStorage.setItem(
    "auth_user",
    JSON.stringify(response.data.user)
);

Objects must be converted to JSON strings before storing them in AsyncStorage.

11. Auth State

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

Auth state allows the application to know whether a user is logged in.

12. Auth Context

interface AuthContextType {
    user: User | null;
    token: string | null;
    login: (
        token: string,
        user: User
    ) => Promise<void>;
    logout: () => Promise<void>;
    loading: boolean;
}

Auth Context provides authentication information throughout the React Native application.

13. Auth Provider

const AuthProvider =
    ({ children }: any) => {

    const [user, setUser] =
        useState<User | null>(null);

    const [token, setToken] =
        useState<string | null>(null);

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

    return (
        <AuthContext.Provider
            value={{
                user,
                token,
                loading
            }}
        >

            {children}

        </AuthContext.Provider>
    );
};

14. Login in Auth Context

const login =
    async (
        newToken: string,
        newUser: User
    ) => {

    await AsyncStorage.setItem(
        "auth_token",
        newToken
    );

    await AsyncStorage.setItem(
        "auth_user",
        JSON.stringify(newUser)
    );

    setToken(newToken);
    setUser(newUser);
};

15. Restore Authentication

When the application starts, it can check AsyncStorage for a saved token and user.

const token =
    await AsyncStorage.getItem(
        "auth_token"
    );

const userData =
    await AsyncStorage.getItem(
        "auth_user"
    );

16. Restore User Object

if (token && userData) {

    setToken(token);

    setUser(
        JSON.parse(userData)
    );
}

JSON.parse converts the stored JSON string back into a JavaScript object.

17. Axios Request Interceptor

api.interceptors.request.use(
    async config => {

        const token =
            await AsyncStorage.getItem(
                "auth_token"
            );

        if (token) {

            config.headers.Authorization =
                `Bearer ${token}`;
        }

        return config;
    }
);

The interceptor automatically adds the JWT to protected requests.

18. Protected API Request

const response =
    await api.get(
        "/students.php"
    );

The application does not need to manually add the Authorization header every time if the Axios interceptor handles it.

19. PHP JWT Verification

$authHeader =
    $_SERVER['HTTP_AUTHORIZATION']
    ?? '';

if (
    !preg_match(
        '/Bearer\s+(.+)/',
        $authHeader,
        $matches
    )
) {

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" =>
            "Authentication required."
    ]);

    exit;
}

$token = $matches[1];

20. Decode and Verify JWT

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$decoded = JWT::decode(
    $token,
    new Key(
        $secretKey,
        'HS256'
    )
);

The server verifies the token before allowing access to protected resources.

21. Identify the User

$userId =
    $decoded->sub;

$userEmail =
    $decoded->email;

$userRole =
    $decoded->role;

The JWT payload can contain information used to identify the authenticated user and determine permissions.

22. Role-Based Authorization

if ($userRole !== 'admin') {

    http_response_code(403);

    echo json_encode([
        "success" => false,
        "message" =>
            "Permission denied."
    ]);

    exit;
}

Authentication alone does not give every user permission to perform every action.

23. Authentication-Based Navigation

if (loading) {

    return <LoadingScreen />;

}

if (!user) {

    return <AuthNavigator />;

}

return <AppNavigator />;

The root navigation can decide which navigation stack should be displayed.

24. Authenticated Application Screens

AppNavigator

├── Student List
├── Student Details
├── Add Student
├── Edit Student
├── Search Student
├── Profile
└── Logout

These screens are available after successful authentication.

25. Logout Flow

Logout
   ↓
Remove JWT
   ↓
Remove User
   ↓
Clear Auth State
   ↓
Auth Navigator
   ↓
Login Screen
await AsyncStorage.removeItem(
    "auth_token"
);

await AsyncStorage.removeItem(
    "auth_user"
);

setToken(null);
setUser(null);

26. Complete Authentication Flow Example

const loginUser =
    async (
        email: string,
        password: string
    ) => {

    const response =
        await api.post<LoginResponse>(
            "/login.php",
            {
                email,
                password
            }
        );

    const token =
        response.data.token;

    const user =
        response.data.user;

    await AsyncStorage.setItem(
        "auth_token",
        token
    );

    await AsyncStorage.setItem(
        "auth_user",
        JSON.stringify(user)
    );

    setToken(token);
    setUser(user);
};

27. Persistent Login Flow

App Starts
    ↓
Check AsyncStorage
    ↓
JWT Found?
    ↓
Yes
    ↓
Validate Token / Profile
    ↓
Valid?
    ├── Yes → AppNavigator
    └── No  → Remove Token
                 ↓
              Login Screen

No Token
    ↓
Login Screen

The application can verify the stored authentication before showing protected screens.

28. Complete Project Architecture

React Native
     │
     ├── Login Screen
     │
     ├── Registration Screen
     │
     ├── Auth Context
     │
     ├── AsyncStorage
     │
     ├── Axios
     │
     └── Navigation
             │
             ↓
          PHP REST API
             │
             ├── Registration
             ├── Login
             ├── JWT Verification
             ├── Student CRUD
             ├── Search
             └── Profile
             │
             ↓
           MySQL
             │
          users
          students

29. Complete Authentication Lifecycle

1. User registers
        ↓
2. Password is hashed
        ↓
3. User logs in
        ↓
4. password_verify()
        ↓
5. PHP creates JWT
        ↓
6. React Native receives JWT
        ↓
7. JWT stored locally
        ↓
8. Auth Context stores user
        ↓
9. AppNavigator opens
        ↓
10. Axios sends Bearer token
        ↓
11. PHP verifies JWT
        ↓
12. Protected API executes
        ↓
13. User logs out
        ↓
14. Local token removed
        ↓
15. Login screen appears

30. Project Authentication Summary

The authentication flow connects all major authentication components of our Student Management mobile application.

  • Registration creates the user account.
  • Passwords are securely hashed on the server.
  • Login verifies the password using password_verify().
  • PHP creates a JWT after successful login.
  • React Native stores the token locally.
  • Auth Context manages authentication state.
  • Axios interceptors send the JWT with protected requests.
  • PHP verifies the JWT before serving protected APIs.
  • Roles can be used for authorization.
  • Protected navigation displays authenticated screens.
  • Persistent login can restore the session after an app restart.
  • Logout removes local authentication information.
  • The next lesson is the final mobile application project.

📌 Key Points

  • Registration and login are separate authentication steps.
  • JWT identifies an authenticated API client.
  • AsyncStorage can persist the authentication token.
  • Auth Context provides authentication state throughout the app.
  • Axios interceptors can automatically attach JWT tokens.
  • Protected APIs must verify JWTs on the server.
  • Authentication and authorization are different concepts.
  • Role-based authorization can restrict administrative operations.
  • Navigation can depend on authentication state.
  • Logout should clear the locally stored authentication data.

🧠 Quick Quiz

Question: Where should the JWT be verified before allowing access to a protected REST API?