Lesson 42 โ€ข Advanced

    RBAC & ACL Permissions ๐Ÿ”’

    Implement role-based access control with role hierarchies, permission middleware, and database-backed authorization for PHP applications.

    What You'll Learn in This Lesson

    • โ€ข Difference between RBAC and ACL approaches
    • โ€ข Define roles with permissions and inheritance hierarchies
    • โ€ข Build permission middleware for route protection
    • โ€ข Design the database schema for roles and permissions
    • โ€ข Check access with can() and requireAny() patterns

    Role-Based Access Control

    RBAC assigns permissions to roles (not directly to users), then assigns roles to users. Role hierarchies let admin inherit all editor and viewer permissions automatically. This scales to thousands of users โ€” change a role's permissions once, and it applies to everyone with that role.

    Try It: RBAC System

    Define roles with inheritance, assign to users, and check access

    Try it Yourself ยป
    JavaScript
    // Role-Based Access Control (RBAC) in PHP
    console.log("=== RBAC vs ACL โ€” What's the Difference? ===");
    console.log();
    console.log("  RBAC (Role-Based):");
    console.log("    Users โ†’ Roles โ†’ Permissions");
    console.log("    'Alice is an Editor, Editors can publish posts'");
    console.log("    โœ… Simple, scalable, most common");
    console.log();
    console.log("  ACL (Access Control List):");
    console.log("    Users โ†’ Specific Resource Permissions");
    console.log("    'Alice can edit Post #42 specifically'");
    ...

    Permission Middleware & Schema

    Protect routes with middleware that checks permissions before the controller runs. If the user lacks the required permission, return 403 Forbidden. The database schema uses pivot tables (role_permissions, user_roles) for many-to-many relationships.

    Try It: Permission Middleware

    Protect routes with permission checks and see the database schema

    Try it Yourself ยป
    JavaScript
    // Permission Middleware & Database Schema
    console.log("=== Permission Middleware Pattern ===");
    console.log();
    
    class PermissionMiddleware {
      constructor(rbac) { this.rbac = rbac; }
    
      require(permission) {
        return (request) => {
          let userId = request.userId;
          let allowed = this.rbac.can(userId, permission);
          
          if (!allowed) {
            console.log("  ๐Ÿšซ 403 Forbidden: " + request.method + " " + request.path);
            console.log("     User " + userId + " lacks permission:
    ...

    โš ๏ธ Common Mistakes

    โš ๏ธ
    Checking roles instead of permissions โ€” Don't write if (user.role === 'admin'). Check if (user.can('users.delete')). This way, adding a new role doesn't require changing code.
    โš ๏ธ
    Client-side only authorization โ€” Hiding a button doesn't prevent the action. Always enforce permissions on the server. The frontend is just UX polish.
    ๐Ÿ’ก
    Pro Tip: Cache user permissions in the session after login. Query the database only once per session, not on every request.

    ๐Ÿ“‹ Quick Reference โ€” Authorization

    PatternDescription
    RBACUsers โ†’ Roles โ†’ Permissions
    ACLUsers โ†’ Specific resource permissions
    Pivot TableMany-to-many relationship table
    MiddlewarePre-controller permission check
    Gate/PolicyLaravel's authorization abstractions

    ๐ŸŽ‰ Lesson Complete!

    You can now build authorization systems! Next, learn to abstract file storage across local, S3, and cloud providers.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy Policy โ€ข Terms of Service