Authorisation
Also Known As
TL;DR
Explanation
Authorisation (authz) answers 'what can this user do?' — distinct from authentication ('who is this user?'). After a user authenticates, every protected action must check whether that user has permission. Authorisation models: RBAC (roles with permissions assigned to users — the most common PHP pattern); ABAC (attribute-based, evaluates resource + user + environment attributes); ACL (per-resource permission lists — flexible but hard to manage at scale). In PHP frameworks: Laravel uses Gates (closure-based checks) and Policies (model-specific classes with methods like view, create, update, delete — automatically mapped to controller actions via $this->authorize()); Symfony uses Voters (classes that implement the vote() method for granular attribute-based decisions). The most critical authorisation rule: check on every request, never rely on hiding UI elements as the only control — a hidden button is not an access control.
Common Misconception
Why It Matters
Common Mistakes
- Checking authorisation only in the UI layer — always enforce server-side on every request.
- Using the authenticated user's ID from user input instead of the session — always read the user ID from the session, never from POST/GET parameters.
- Missing authorisation on API endpoints when the web routes are protected — both must be checked independently.
- Not testing authorisation — write tests that verify a user cannot access another user's resources.
Code Examples
// Missing authorisation — any user can view any order
class OrderController {
public function show(int $id): array {
return Order::findOrFail($id)->toArray();
// User 1 can access /orders/999 (belongs to user 2)
}
}
// Authorisation check before returning data
class OrderController {
public function show(Order $order): array {
// Laravel Policy — checks order->user_id === auth()->id()
$this->authorize('view', $order);
return $order->toArray();
}
}
// OrderPolicy
class OrderPolicy {
public function view(User $user, Order $order): bool {
return $user->id === $order->user_id
|| $user->hasRole('admin');
}
}