Authentication is an important part of REST API development. In a React Native application, authentication allows the server to identify the user making an API request.
Authentication is the process of verifying the identity of a user.
For example:
After successful authentication, the server can identify the user.
Authentication and authorization are different concepts.
For example, a user may successfully log in but still not have permission to access an admin API.
Common API authentication approaches include:
Basic Authentication sends a username and password as part of the HTTP Authorization header.
Authorization: Basic base64(username:password)
HTTPS should be used when transmitting credentials.
An API key is a value that identifies an application or client.
X-API-Key: YOUR_API_KEY
API keys are commonly used for service-to-service access and identifying applications.
Sensitive API keys should not be treated as a replacement for user authentication in a mobile application.
Traditional web applications often use sessions.
Login
↓
PHP Session
↓
Session Cookie
↓
Protected Request
Session-based authentication is commonly associated with server-side web applications.
Token authentication uses a token to identify an authenticated user.
Authorization: Bearer YOUR_TOKEN
The mobile application sends the token with protected API requests.
JSON Web Token, or JWT, is a popular token format used by REST APIs.
Authorization: Bearer JWT_TOKEN
The server verifies the JWT before allowing access to protected resources.
A JWT normally contains three parts:
Header.Payload.Signature
The signature helps the server verify that the token has not been altered.
React Native Login
↓
PHP Login API
↓
Verify User
↓
Create Token
↓
Return Token
↓
React Native
↓
Protected API Request
↓
Verify Token
TypeScript can describe authentication data using interfaces.
interface AuthUser {
id: number;
name: string;
email: string;
}
interface LoginRequest {
email: string;
password: string;
}
This interface describes the data sent to the login API.
interface LoginResponse {
success: boolean;
message: string;
token: string;
user: AuthUser;
}
This represents a common login response containing a token and user data.
const data: LoginRequest = {
email: "user@example.com",
password: "123456"
};
const response =
await api.post<LoginResponse>(
"/login",
data
);
console.log(response.data.token);
A bearer token is commonly sent using the Authorization header.
Authorization: Bearer YOUR_TOKEN
The server extracts the token and verifies it before processing a protected request.
interface AuthToken {
token: string;
}
A more complete authentication state can contain both the token and the authenticated user.
interface AuthState {
token: string | null;
user: AuthUser | null;
isAuthenticated: boolean;
}
React Native can store authentication state using TypeScript.
const [auth, setAuth] =
useState<AuthState>({
token: null,
user: null,
isAuthenticated: false
});
setAuth({
token: response.data.token,
user: response.data.user,
isAuthenticated: true
});
After successful login, the application can update its authentication state.
const response =
await api.get("/profile", {
headers: {
Authorization:
`Bearer ${token}`
}
});
The Authorization header tells the server which token should be verified.
Axios interceptors can automatically add authentication headers.
api.interceptors.request.use(config => {
if (token) {
config.headers.Authorization =
`Bearer ${token}`;
}
return config;
});
This avoids manually adding the token to every API request.
interface AuthError {
success: false;
message: string;
code?: string;
}
This can represent authentication-related API errors.
{
"success": false,
"message": "Invalid credentials",
"code": "INVALID_CREDENTIALS"
}
A protected API can return HTTP 401 when authentication
is missing or invalid.
{
"success": false,
"message": "Authentication required"
}
React Native can detect this response and ask the user to log in again.
HTTP 403 usually indicates that the authenticated user
does not have permission to access the requested resource.
{
"success": false,
"message": "Access denied"
}
This is especially useful for role-based authorization.
Authentication identifies the user. A role can then be used to determine what the user is allowed to access.
interface AuthUser {
id: number;
name: string;
email: string;
role: "admin" | "teacher" | "student";
}
The server should enforce authorization; the mobile UI should not be treated as the security boundary.
A mobile application needs a way to retain authentication information when appropriate.
Common options include:
Sensitive authentication tokens should be stored using an appropriate secure storage approach for the application.
The mobile application should never store a user's plain-text password as an authentication mechanism.
Passwords should be sent over HTTPS to the login API and securely processed by the server. The server should store passwords using password hashing rather than plain text.
interface AuthUser {
id: number;
name: string;
email: string;
role: "admin" | "teacher" | "student";
}
interface LoginRequest {
email: string;
password: string;
}
interface LoginResponse {
success: boolean;
message: string;
token: string;
user: AuthUser;
}
interface AuthState {
token: string | null;
user: AuthUser | null;
isAuthenticated: boolean;
}
import axios from "axios";
interface AuthUser {
id: number;
name: string;
email: string;
role: "admin" | "teacher" | "student";
}
interface LoginRequest {
email: string;
password: string;
}
interface LoginResponse {
success: boolean;
message: string;
token: string;
user: AuthUser;
}
const login = async (
data: LoginRequest
): Promise<LoginResponse> => {
const response =
await axios.post<LoginResponse>(
"https://example.com/api/login",
data
);
return response.data;
};
The function accepts a typed login request and returns a typed login response.
React Native Login Screen
↓
LoginRequest Interface
↓
Axios POST
↓
PHP Login API
↓
Verify Email + Password
↓
Create Token / JWT
↓
LoginResponse
↓
React Native AuthState
↓
Authorization Header
↓
Protected PHP API
↓
Verify Token
↓
Return Protected Data
TypeScript interfaces provide a clear structure for authentication requests, responses, users, tokens, and authentication state.
The PHP API remains responsible for securely verifying credentials, validating tokens, and enforcing authorization.
Question: Which HTTP status code commonly indicates that authentication is missing or invalid?