Authorization
Authentication answers “who are you?”. Authorization answers “may you do this?”. NaluzPHP provides authentication but does not include a Gate, policy classes or roles. Authorization is plain PHP in middleware, controllers and resolvers. That keeps the checks explicit and easy to audit.
Pattern 1: middleware for whole route groups
Section titled “Pattern 1: middleware for whole route groups”final class EnsureAdmin implements MiddlewareInterface{ public function __construct(private readonly Auth $auth) {}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { if (!$this->auth->user()?->is_admin) { throw new HttpException(403, 'Admins only.'); } return $handler->handle($request); }}$router->prefix('admin')->middleware(['auth', 'admin'])->group(function ($router) { … });Pattern 2: ownership checks in the controller
Section titled “Pattern 2: ownership checks in the controller”public function update(ServerRequestInterface $request, int $post): Post{ $model = Post::findOrFail($post);
if ((int) $model->user_id !== (int) $request->getAttribute('auth.id')) { throw new HttpException(403, 'You can only edit your own posts.'); } // …}Better still, scope the query so a record the user may not touch simply does not exist for them:
$post = Post::where('user_id', $userId)->findOrFail($id); // 404 for other people's postsPattern 3: a reusable policy class
Section titled “Pattern 3: a reusable policy class”final class PostPolicy{ public function update(User $user, Post $post): bool { return $user->id === $post->user_id || $user->is_admin; }}
// in a controllerif (!app(PostPolicy::class)->update($user, $post)) { throw new HttpException(403);}Resolve it from the container so it can use injected dependencies.
Authorization in GraphQL
Section titled “Authorization in GraphQL”Resolvers receive the PSR-7 request as $context. Check auth.id there and throw a GraphQLError with a code such as
UNAUTHENTICATED or FORBIDDEN. See the GraphQL page.
Checklist
Section titled “Checklist”- Authorize on every write path, not only in the UI.
- Prefer scoping queries to the current user over checking after loading.
- Return
403for “you may not” and404when the existence of the record should not be revealed. - Never trust identifiers in the request body for ownership (take the user from the token or session).