Role-Based Authorization controls what an authenticated user is allowed to do based on the user's role. In a REST API, roles can be used to give different permissions to administrators, teachers, students, and other users.
Role-Based Authorization, commonly called RBAC, is a system where permissions are assigned according to a user's role.
Admin
↓
Full Access
Teacher
↓
Manage Assignments
Student
↓
View Own Data
| Concept | Question |
|---|---|
| Authentication | Who are you? |
| Authorization | What are you allowed to do? |
A user must normally be authenticated before the API can make an authorization decision.
A mobile application might have roles such as:
The exact roles depend on the requirements of the application.
An administrator generally has access to management operations.
These permissions should be enforced on the server, not only in the React Native interface.
A student may have limited access to the API.
Student
Allowed:
✔ View own profile
✔ View own courses
✔ View own assignments
Not Allowed:
✘ Delete users
✘ Manage courses
✘ Access admin reports
A simple application can store a user's role in the users table.
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role VARCHAR(30) NOT NULL DEFAULT 'student'
);
id name role
--------------------------------
1 Rahul admin
2 Amit teacher
3 Neha student
4 Pooja student
The API can use the role value when checking permissions.
A JWT can contain a role claim when the application design requires it.
{
"sub": 10,
"email": "rahul@example.com",
"role": "admin",
"iat": 1760000000,
"exp": 1760003600
}
The server can use the verified role information when making an authorization decision.
A client should not be allowed to decide its own role.
{
"email": "student@example.com",
"role": "admin"
}
The server must obtain the trusted role from authenticated server-side information such as the database or a properly verified token.
if ($user['role'] !== 'admin') {
http_response_code(403);
echo json_encode([
"success" => false,
"message" => "Admin access required"
]);
exit;
}
HTTP status 403 Forbidden is appropriate when the authenticated user does not have permission.
Role checking can be placed into reusable middleware.
function requireRole($user, $requiredRole)
{
if ($user['role'] !== $requiredRole) {
http_response_code(403);
echo json_encode([
"success" => false,
"message" => "Access forbidden"
]);
exit;
}
}
requireRole($user, 'admin');
echo json_encode([
"success" => true,
"message" => "Admin operation allowed"
]);
Only an authenticated user with the required role can continue.
Sometimes multiple roles should have access to the same endpoint.
$allowedRoles = [
'admin',
'teacher'
];
if (!in_array(
$user['role'],
$allowedRoles,
true
)) {
http_response_code(403);
echo json_encode([
"success" => false,
"message" => "Access forbidden"
]);
exit;
}
Suppose an API allows only administrators to delete users.
DELETE /api/users.php?id=10
Authentication
↓
Identify User
↓
Check Role
↓
Admin?
↙ ↘
Yes No
↓ ↓
Delete 403
requireAuth();
$user = getAuthenticatedUser();
requireRole($user, 'admin');
// Admin-only operation
$stmt = $pdo->query(
"SELECT id, name, email, role
FROM users"
);
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([
"success" => true,
"message" => "Users retrieved successfully",
"data" => $users
]);
An endpoint can allow both administrators and teachers to manage assignments.
$allowedRoles = [
'admin',
'teacher'
];
if (!in_array(
$user['role'],
$allowedRoles,
true
)) {
http_response_code(403);
echo json_encode([
"success" => false,
"message" => "Teacher or admin access required"
]);
exit;
}
Role-based authorization alone is sometimes not enough. A student may be allowed to view student data, but only their own data.
Student
↓
Can view profile
↓
Only own profile
The API should check both the user's role and the ownership of the resource.
$requestedStudentId = $_GET['id'];
if (
$user['role'] === 'student' &&
$user['student_id'] != $requestedStudentId
) {
http_response_code(403);
echo json_encode([
"success" => false,
"message" => "You cannot access this student"
]);
exit;
}
This prevents a student from accessing another student's information simply by changing an ID in the URL.
Larger applications may use permissions instead of checking only roles.
admin:
users.view
users.create
users.update
users.delete
teacher:
assignments.view
assignments.create
assignments.update
student:
profile.view
assignment.view
A role can be associated with several permissions.
| Role | Example Permission |
|---|---|
| Admin | Delete users |
| Teacher | Create assignments |
| Student | View own assignments |
Roles are convenient groups of permissions.
When an authenticated user does not have sufficient permission, the API can return HTTP 403.
http_response_code(403);
echo json_encode([
"success" => false,
"message" => "You do not have permission to perform this action",
"data" => null
]);
React Native can use the authenticated user's role to display appropriate screens or buttons.
if (user.role === "admin") {
// Show Admin Dashboard
}
if (user.role === "student") {
// Show Student Dashboard
}
const response = await fetch(
"https://example.com/api/admin/users.php",
{
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
}
);
const result = await response.json();
if (response.status === 403) {
console.log("Access denied");
}
try {
const response = await axios.get(
API_URL,
{
headers: {
Authorization: `Bearer ${token}`
}
}
);
console.log(response.data);
} catch (error) {
if (error.response?.status === 403) {
console.log("Access denied");
}
}
Admin endpoints should verify both authentication and authorization.
Request
↓
JWT Verification
↓
User Identified
↓
Role Check
↓
Admin?
↓
Admin API
Never assume that a URL containing admin automatically makes an endpoint secure.
React Native
↓
Bearer JWT
↓
Authentication Middleware
↓
Identify User
↓
Read Verified Role
↓
Authorization Middleware
↓
Permission Check
↓
API Endpoint
↓
Database
↓
JSON Response
function requireRoles($user, $allowedRoles)
{
if (!in_array(
$user['role'],
$allowedRoles,
true
)) {
http_response_code(403);
echo json_encode([
"success" => false,
"message" => "Access forbidden",
"data" => null
]);
exit;
}
}
// Authentication should happen first
requireAuth();
$user = getAuthenticatedUser();
// Admin and teacher can continue
requireRoles($user, [
'admin',
'teacher'
]);
// Protected operation here
React Native Mobile App
↓
API Request
↓
Authentication
↓
JWT Verified
↓
Identify User
↓
Check User Role
↓
Check Permission
↓
Check Ownership
↓
API Endpoint
↓
MySQL
↓
Standard JSON
Response
This architecture provides a strong foundation for secure role-based REST APIs used by React Native applications.
Question: Which HTTP status code is commonly returned when an authenticated user does not have permission to access a resource?