Most Developers Design Permissions Wrong!

Most Developers Design Permissions Wrong!

Permission systems are one of the most misunderstood parts of backend development. Many developers build systems that work… until they scale — then everything breaks.

If you've ever hardcoded roles like admin = true, this guide is for you.

Common Mistakes Developers Make

Before fixing it, let’s understand the problems:

1. Hardcoding Roles

if ($user->is_admin) {
// allow everything
}

👉 Not scalable. What if you need editor, moderator, manager?

2. Mixing Roles and Permissions

if ($user->role == 'admin' || $user->role == 'editor') {
// allow edit
}

👉 Roles should NOT define logic directly.

3. No Granular Control

  • Can’t control create / read / update / delete separately
  • Everything becomes “all or nothing”

4. No Future Flexibility

  • Adding new features = rewriting authorization logic

The Correct Design (Industry Standard)

Modern systems use 3 layers:

🔹 1. Permissions (Atomic Level)

Smallest unit of access:

  • user.create
  • user.read
  • user.update
  • user.delete

🔹 2. Roles (Group of Permissions)

Roles are just collections of permissions:

  • Admin → all permissions
  • Editor → create, read, update
  • Viewer → read only

🔹 3. Users (Assigned Roles)

Users get access via roles:

User → Role → Permissions

Think Like This

❌ Wrong: "User is admin → allow everything"
✅ Right: "User has permission → allow action"

Step-by-Step Implementation

Step 1: Database Design

Tables

users

id, name, email, password

roles

id, name

permissions

id, name

role_user (Pivot)

user_id, role_id

permission_role (Pivot)

role_id, permission_id

Step 2: Define Permissions

Example:

[
'user.create',
'user.read',
'user.update',
'user.delete'
]

Step 3: Assign Permissions to Roles

Admin:
- user.create
- user.read
- user.update
- user.delete

Editor:
- user.create
- user.read
- user.update

Viewer:
- user.read

Step 4: Assign Roles to Users

$user->roles()->attach($roleId);

Step 5: Check Permissions (Important!)

❌ Wrong Way

if ($user->role == 'admin')

✅ Correct Way

if ($user->hasPermission('user.update')) {
// allow
}

Step 6: Create Helper Function

public function hasPermission($permission)
{
return $this->roles()
->with('permissions')
->get()
->pluck('permissions')
->flatten()
->pluck('name')
->contains($permission);
}

Step 7: Middleware (Laravel Example)

public function handle($request, Closure $next, $permission)
{
if (!auth()->user()->hasPermission($permission)) {
abort(403, 'Unauthorized');
}

return $next($request);
}

Usage:

Route::get('/users', function () {
//
})->middleware('permission:user.read');

Advanced Best Practices

1. Use Naming Convention

resource.action
post.create
post.update
order.approve

2. Use Caching

Permission checks can be expensive:

Cache::remember('user_permissions_'.$user->id, 60, function () {
return ...
});

3. Avoid Role Explosion

❌ Bad:

  • admin_us
  • admin_eu
  • admin_asia

✅ Better:

  • Use permissions like:
    • manage.users.us
    • manage.users.eu

4. Dynamic Permission System (Recommended)

Store everything in DB so admin can manage:

  • Create roles from UI
  • Assign permissions dynamically
  • No code changes needed 🔥

5. Use Packages (Laravel)

If using Laravel, use:

👉 Spatie Laravel Permission

Why?

  • Production-ready
  • Handles roles & permissions easily
  • Built-in middleware
  • Widely used in industry

Example Real-World Scenario

E-commerce System

RolePermissions
AdminAll
Managerorders., products.
Stafforders.read, orders.update
Customerorders.create, orders.read

Final Thoughts

If you remember ONE thing:

👉 Never check roles directly — always check permissions

Summary

✔ Use permissions as the source of truth
✔ Roles = grouping only
✔ Users = assigned roles
✔ Always check permissions

✔ Keep it dynamic and scalable 

Souy Soeng

Souy Soeng

Hi there 👋, I’m Soeng Souy (StarCode Kh)
-------------------------------------------
🌱 I’m currently creating a sample Laravel and React Vue Livewire
👯 I’m looking to collaborate on open-source PHP & JavaScript projects
💬 Ask me about Laravel, MySQL, or Flutter
⚡ Fun fact: I love turning ☕️ into code!

Post a Comment

CAN FEEDBACK
close