Lesson 130 of 158 – React Native Axios Token
82%

React Native Axios Token

In the previous lessons, we learned how to create JWT tokens and store authentication information in React Native. Now we will use Axios to automatically send the JWT token with protected API requests.

Note: The JWT signing secret must remain on the PHP server. React Native only receives and sends the access token. The server must verify the token before returning protected data.

1. What is an Axios Token Request?

An authenticated Axios request includes the JWT token in the Authorization header.

Authorization: Bearer YOUR_JWT_TOKEN

This allows the PHP API to identify the authenticated user.

2. Authentication Request Flow

Login
  ↓
PHP Login API
  ↓
JWT Token
  ↓
React Native
  ↓
Store Token
  ↓
Axios Request
  ↓
Authorization Header
  ↓
PHP JWT Verification
  ↓
Protected Data

3. Importing Axios

import axios from "axios";

Axios provides methods such as get(), post(), put(), and delete() for communicating with REST APIs.

4. Creating an Axios Instance

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

The Axios instance provides a common configuration for API requests.

5. Getting the Stored Token

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

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

The returned value is either a string or null.

6. Token Type in TypeScript

const token: string | null =
    await AsyncStorage.getItem(
        "authToken"
    );

TypeScript requires us to handle the possibility that the token does not exist.

7. Sending Token Manually

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

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

8. Checking the Token Before Request

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

if (!token) {

    console.log(
        "Authentication required"
    );

    return;
}

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

9. User Interface Type

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

10. Typed Profile Response

interface UserResponse {
    success: boolean;
    message: string;
    user: User;
}

Axios can use this interface to provide type checking for the API response.

11. Typed Axios Token Request

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

console.log(
    response.data.user.name
);

12. Creating a Token Helper

const getToken =
    async (): Promise<
        string | null
    > => {

    return await AsyncStorage.getItem(
        "authToken"
    );
};

A helper function avoids repeating the AsyncStorage code.

13. Protected API Function

const getProfile =
    async (): Promise<UserResponse> => {

    const token =
        await getToken();

    if (!token) {
        throw new Error(
            "Authentication required"
        );
    }

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

    return response.data;
};

14. Axios Request Interceptor

An Axios request interceptor can automatically add the token to requests.

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

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

        if (token) {

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

        return config;
    }
);

15. Why Use an Interceptor?

Without an interceptor, every protected request may need to manually add the Authorization header.

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

api.get("/students.php", {
    headers: {
        Authorization: `Bearer ${token}`
    }
});

An interceptor centralizes this repeated behavior.

16. Axios Interceptor with Token Helper

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

        const token =
            await getToken();

        if (token) {

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

        return config;
    }
);

Now the token can be added automatically before the request is sent.

17. Protected GET Request

const response =
    await api.get<UserResponse>(
        "/profile.php"
    );

console.log(
    response.data.user.name
);

If the interceptor is configured correctly, the token is added automatically.

18. Protected POST Request

const response =
    await api.post(
        "/students.php",
        {
            name: "Ravi",
            course: "React Native"
        }
    );

The request interceptor can also attach the JWT to POST requests.

19. Protected PUT Request

const response =
    await api.put(
        "/students.php?id=10",
        {
            name: "Ravi Kumar",
            course: "TypeScript"
        }
    );

The same authentication mechanism can protect update operations.

20. Protected DELETE Request

const response =
    await api.delete(
        "/students.php?id=10"
    );

The JWT is also available to protected DELETE endpoints through the interceptor.

21. Handling 401 Response

If the JWT is missing, invalid, or expired, the server may return HTTP 401.

try {

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

} catch (error) {

    if (
        axios.isAxiosError(error) &&
        error.response?.status === 401
    ) {

        console.log(
            "Please login again"
        );
    }
}

22. Response Interceptor

A response interceptor can centralize handling of authentication errors.

api.interceptors.response.use(

    response => response,

    async error => {

        if (
            error.response?.status === 401
        ) {

            await AsyncStorage.removeItem(
                "authToken"
            );

            console.log(
                "Authentication expired"
            );
        }

        return Promise.reject(error);
    }
);

23. Token and Authentication State

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

The token stored locally and the current authentication state should be kept consistent.

24. Axios Token Service

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

export const getToken =
    async (): Promise<
        string | null
    > => {

    return await AsyncStorage.getItem(
        "authToken"
    );
};

export const saveToken =
    async (token: string) => {

    await AsyncStorage.setItem(
        "authToken",
        token
    );
};

export const removeToken =
    async () => {

    await AsyncStorage.removeItem(
        "authToken"
    );
};

25. Complete Axios Configuration

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

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

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

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

        if (token) {

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

        return config;
    }
);

export default api;

26. Complete Login and Token Flow

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

if (result.success) {

    await AsyncStorage.setItem(
        "authToken",
        result.token
    );

    console.log(
        "Login successful"
    );
}

Future requests made through the configured Axios instance can automatically use this token.

27. Complete Protected API Service

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

interface UserResponse {
    success: boolean;
    message: string;
    user: User;
}

export const getProfile =
    async (): Promise<UserResponse> => {

    const response =
        await api.get<UserResponse>(
            "/profile.php"
        );

    return response.data;
};

export const getStudents =
    async () => {

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

    return response.data;
};

28. Complete React Native API Example

const loadProfile = async () => {

    try {

        setLoading(true);

        const result =
            await getProfile();

        if (result.success) {

            setUser(result.user);
        }

    } catch (error) {

        if (
            axios.isAxiosError(error) &&
            error.response?.status === 401
        ) {

            setError(
                "Please login again"
            );

        } else {

            setError(
                "Unable to load profile"
            );
        }

    } finally {

        setLoading(false);
    }
};

29. Axios Token Architecture

Login API
    ↓
JWT Token
    ↓
AsyncStorage
    ↓
Axios Request Interceptor
    ↓
Authorization: Bearer JWT
    ↓
PHP Protected API
    ↓
JWT Verification
    ↓
Protected Response
    ↓
Axios Response
    ↓
React Native UI

This architecture keeps authentication logic centralized and avoids manually adding the JWT to every protected request.

30. Complete React Native Axios JWT Flow

1. User logs in
2. PHP verifies credentials
3. PHP returns JWT
4. React Native stores the token
5. Axios instance is configured
6. Request interceptor reads the token
7. Authorization header is added
8. Protected API receives the request
9. PHP verifies the JWT
10. PHP returns protected data
11. React Native displays the data
12. 401 response can trigger authentication cleanup

Axios interceptors provide a clean way to connect JWT authentication with React Native REST APIs. TypeScript interfaces can be used to strongly type login responses, protected API responses, and user data.

📌 Key Points

  • Axios can send JWT tokens through the Authorization header.
  • AsyncStorage can provide persistent access to a locally stored token.
  • TypeScript can define the token as string | null.
  • Axios request interceptors can automatically attach authentication tokens.
  • Protected GET, POST, PUT, and DELETE requests can use the same token mechanism.
  • Response interceptors can centralize handling of 401 responses.
  • The PHP server must verify every protected JWT.
  • The JWT signing secret must remain on the server.
  • Expired or invalid tokens should not be accepted by the API.
  • Secure storage should be considered for sensitive authentication tokens.

🧠 Quick Quiz

Question: Which Axios feature can automatically add a JWT token before every request?