Skip to main content
RESTful Principles
CHAPTER 17 Beginner

REST API Authorization

Updated: May 13, 2026
5 min read

# CHAPTER 17

REST API Authorization

1. Introduction

Authentication answers the question: "Who are you?" Authorization answers the question: "Are you allowed to do this?" Just because a user is logged in does not mean they should be allowed to delete the database or view another user's private messages. In Chapter 17, we will explore Authorization. We will implement Role-Based Access Control (RBAC) and learn how to secure individual endpoints based on user permissions.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Clearly distinguish between Authentication and Authorization.
  • Understand the concept of Role-Based Access Control (RBAC).
  • Implement endpoint-level authorization checks in PHP.
  • Implement resource-level authorization checks (Ownership).
  • Return the correct HTTP status codes for authorization failures.

3. Beginner-Friendly Explanation

Think of a hospital.
  • When an employee swipes their badge at the front door to get in, that is Authentication. The hospital knows it is John.
  • When John tries to swipe his badge to enter the surgical ward, the door denies him because he is a janitor, not a surgeon. That is Authorization.

In our API, we need to assign "roles" (like Admin, Editor, User) to our users, and check those roles before executing the requested action.

4. Real-World Examples

  • WordPress API: A "Subscriber" can use the GET /posts endpoint to read articles. But if they try to use POST /posts to write an article, the API rejects them. Only "Authors" and "Admins" can POST.
  • Banking App: You are authenticated and authorized to view your own bank account (/accounts/5). But if you try to view another user's account (/accounts/6), you are rejected because you do not own it.

5. Detailed Code Examples

Let's build a simple Authorization middleware check in PHP.
php
1234567891011121314151617181920212223242526272829
<?php
// Assume the user has been authenticated and we have their data
$currentUser = [
    &#039;id' => 5,
    &#039;name' => 'Jane',
    &#039;role' => 'standard_user' // Options: admin, editor, standard_user
];

// Endpoint: DELETE /articles/99

// 1. Endpoint-Level Authorization Check (Role Based)
if ($currentUser[&#039;role'] !== 'admin' && $currentUser['role'] !== 'editor') {
    http_response_code(403); // 403 Forbidden!
    echo json_encode(["error" => "You do not have permission to delete articles."]);
    exit;
}

// 2. Resource-Level Authorization Check (Ownership Based)
// Assume we query the database to find the article
$article = [&#039;id' => 99, 'author_id' => 8];

if ($currentUser[&#039;role'] !== 'admin' && $article['author_id'] !== $currentUser['id']) {
    http_response_code(403);
    echo json_encode(["error" => "You can only delete your own articles."]);
    exit;
}

echo json_encode(["message" => "Article deleted successfully."]);
?>

6. Request/Response Examples

When authorization fails, the server should clearly communicate that the identity is known, but the action is blocked.

Request by standard user:

http
12
DELETE /users/10 HTTP/1.1
Authorization: Bearer valid_token_for_jane

Response:

http
1234567
HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": "Forbidden",
  "message": "Only administrators can delete user accounts."
}

7. HTTP Examples

Remember the critical difference in Status Codes:
  • 401 Unauthorized: The client didn't send a token, or the token is expired/invalid. (Identity unknown).
  • 403 Forbidden: The token is perfectly valid. The server knows who the client is, but refuses to execute the action due to lack of permissions. (Identity known, action denied).

8. JSON Examples

To help frontends build dynamic UIs (like hiding the "Delete" button if the user isn't an admin), you should include the user's role in the login response or profile endpoint.
json
12345678
{
  "user_profile": {
    "id": 5,
    "name": "Jane",
    "role": "admin",
    "permissions": ["create_post", "delete_post", "manage_users"]
  }
}

9. Best Practices

  • Deny by Default: Always assume a user DOES NOT have access to an endpoint unless your code explicitly grants them access. Never default to "allow."
  • Check at the Resource Level: Just because a user has the "Editor" role doesn't mean they can edit *anything*. Always check if resource.ownerid == currentuser.id when users try to modify specific data.
  • Keep Roles Simple: Start with basic roles (admin, user). Only introduce complex granular permissions (like caneditposts, canviewbilling) if the application truly requires it.

10. Common Mistakes

  • Trusting the Frontend: A beginner mistake is hiding the "Admin Panel" button in the frontend React app, but forgetting to secure the actual API endpoint. Hackers don't need buttons; they will just send a DELETE request directly to the API using cURL. ALL security MUST be enforced on the backend API.
  • Using 401 instead of 403: Returning 401 for an authorization failure often causes frontend apps to force the user to log out, resulting in a terrible user experience.

11. Mini Exercises

  1. 1. Scenario: User A tries to edit User B's profile. User A sends a valid JWT token. The API should block this. What HTTP status code should be returned?
*(Answer: 403 Forbidden)*

12. Coding Challenges

Challenge 1: Write a PHP function authorize($userRole, $requiredRolesArray) that returns true if the user's role is inside the array, and false otherwise.

13. MCQs with Answers

Question 1

What status code specifically indicates an Authorization failure (user is known, but blocked)?

Question 2

What does RBAC stand for?

Question 3

Where must authorization checks ultimately be enforced to prevent hacking?

14. Interview Questions

  • Q: Compare and contrast 401 Unauthorized and 403 Forbidden. Give an example of when to use each.
  • Q: Explain the concept of "Resource-Level" ownership authorization vs "Endpoint-Level" role authorization.
  • Q: Why is it dangerous to rely on frontend logic to prevent unauthorized actions?

15. FAQs

Q: How do I handle complex permissions where a user is an admin of one "Group" but a standard user in another "Group"? A: This requires a relational database design. Instead of a single role column on the users table, you create a pivot table (e.g., groupuserroles) that links userid, groupid, and role. Before acting on a group resource, the API queries this table.

16. Summary

In Chapter 17, we learned that Authorization is the final layer of security. While tokens prove identity, Role-Based Access Control dictates permissions. We covered endpoint-level checks (blocking actions based on global roles) and resource-level checks (ensuring users only modify data they own). We also emphasized the critical rule: never trust the frontend; always secure the backend API with 403 Forbidden responses.

17. Next Chapter Recommendation

Our API is now secure, but what happens when a user submits bad data? Proceed to Chapter 18: API Validation and Error Handling to learn how to validate JSON payloads and return beautiful, standardized error messages.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·