Referência v3
Voltar à plataforma

Módulo Auth

Como usar autenticação em qualquer módulo — de forma simples, com uma linha de código.

Filosofia

O módulo Auth é desacoplado — funciona com qualquer entidade que implemente AuthenticatableInterface. A fachada Auth encapsula toda a complexidade em métodos curtos e claros.

O que o módulo Auth oferece

O que você precisaComo fazer
Proteger uma rota (qualquer usuário logado)Auth::user()
Proteger uma rota (só admin)Auth::admin()
Obter o usuário logado no ControllerAuth::current($request)
Obter o ID do usuário logadoAuth::id($request)
Verificar se está logado (lança 401)Auth::check($request)
Verificar se é admin (lança 403)Auth::checkAdmin($request)
Autenticação opcional (conteúdo diferente)Auth::optional()
Rate limit sem autenticaçãoAuth::limit(10)

Protegendo rotas

Importe Auth no Routes/web.php do seu módulo e use como terceiro argumento:

php
<?php
use Src\Kernel\Auth;
use Src\Modules\Produto\Controllers\ProdutoController;

/** @var \Src\Kernel\Contracts\RouterInterface $router */

// Pública — sem autenticação
$router->get('/api/produtos',      [ProdutoController::class, 'listar']);
$router->get('/api/produtos/{id}', [ProdutoController::class, 'buscar']);

// Privada — qualquer usuário logado
$router->get('/api/meus-produtos', [ProdutoController::class, 'meus'], Auth::user());

// Admin — só admin_system
$router->post('/api/admin/produtos',        [ProdutoController::class, 'criar'],    Auth::admin());
$router->put('/api/admin/produtos/{id}',    [ProdutoController::class, 'atualizar'], Auth::admin());
$router->delete('/api/admin/produtos/{id}', [ProdutoController::class, 'deletar'],  Auth::admin());

// Com rate limit — 10 req/min por IP
$router->post('/api/produtos/buscar', [ProdutoController::class, 'buscarAvancado'], Auth::user(limit: 10));

// Admin com rate limit + proteção de banco
$router->post('/api/admin/importar', [ProdutoController::class, 'importar'], Auth::admin(limit: 5, db: true));

Acessando o usuário no Controller

Use a fachada Auth para obter o usuário autenticado dentro do Controller:

php
<?php
namespace Src\Modules\Produto\Controllers;

use Src\Kernel\Auth;
use Src\Kernel\Http\Request\Request;
use Src\Kernel\Http\Response\Response;
use Src\Modules\Produto\Services\ProdutoService;

class ProdutoController
{
    public function __construct(private ProdutoService $service) {}

    // Rota pública — usuário pode ou não estar logado
    public function listar(Request $request): Response
    {
        $userId = Auth::id($request); // null se não logado
        $produtos = $this->service->listar($userId);
        return Response::json(['produtos' => $produtos]);
    }

    // Rota privada — Auth::user() já garante que está logado
    public function meus(Request $request): Response
    {
        $user = Auth::current($request); // nunca null aqui
        $produtos = $this->service->listarPorUsuario($user->getAuthId());
        return Response::json(['produtos' => $produtos]);
    }

    // Rota admin — Auth::admin() já garante que é admin_system
    public function criar(Request $request): Response
    {
        $user = Auth::current($request);
        $produto = $this->service->criar($request->body ?? [], $user->getAuthId());
        return Response::json(['produto' => $produto], 201);
    }

    // Verificação manual dentro do Controller (sem middleware na rota)
    public function deletar(Request $request, string $id): Response
    {
        try {
            Auth::checkAdmin($request); // lança 403 se não for admin_system
            $this->service->deletar($id);
            return Response::json(['message' => 'Removido.']);
        } catch (\DomainException $e) {
            return Response::json(['error' => $e->getMessage()], $e->getCode() ?: 403);
        }
    }
}

Usando Auth com sua própria entidade

O módulo Auth funciona com qualquer entidade — não só com Usuario. Para usar com uma entidade própria (ex: Cliente, Funcionario), siga 3 passos:

1

Implemente AuthenticatableInterface na entidade

php
<?php
namespace Src\Modules\Cliente\Entities;

use Src\Kernel\Contracts\AuthenticatableInterface;

class Cliente implements AuthenticatableInterface
{
    public function __construct(
        private string $id,
        private string $email,
        private string $senhaHash,
        private bool   $ativo
    ) {}

    // Métodos obrigatórios da interface
    public function getAuthId(): string       { return $this->id; }
    public function getAuthEmail(): string    { return $this->email; }
    public function getAuthUsername(): ?string { return null; } // sem username
    public function getAuthRole(): string     { return 'cliente'; }
    public function isAtivo(): bool           { return $this->ativo; }
    public function isEmailVerificado(): bool { return true; }

    public function verificarSenha(string $senha): bool
    {
        return password_verify($senha, $this->senhaHash);
    }
}
2

Implemente UserRepositoryInterface no Repository

php
<?php
namespace Src\Modules\Cliente\Repositories;

use PDO;
use Src\Kernel\Contracts\UserRepositoryInterface;
use Src\Modules\Cliente\Entities\Cliente;

class ClienteRepository implements UserRepositoryInterface
{
    public function __construct(private PDO $pdo) {}

    public function buscarPorEmail(string $email): ?object
    {
        $stmt = $this->pdo->prepare('SELECT * FROM clientes WHERE email = :e LIMIT 1');
        $stmt->execute([':e' => $email]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ? new Cliente($row['id'], $row['email'], $row['senha_hash'], (bool)$row['ativo']) : null;
    }

    public function buscarPorUsername(string $username): ?object { return null; }
    public function buscarPorUuid(string $uuid): ?object
    {
        $stmt = $this->pdo->prepare('SELECT * FROM clientes WHERE id = :id LIMIT 1');
        $stmt->execute([':id' => $uuid]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ? new Cliente($row['id'], $row['email'], $row['senha_hash'], (bool)$row['ativo']) : null;
    }

    // Stubs obrigatórios pela interface — implemente se precisar
    public function marcarEmailComoVerificado(string $uuid, bool $v = true): void {}
    public function salvarTokenRecuperacaoSenha(string $uuid, string $token): void {}
    public function buscarPorTokenRecuperacaoSenha(string $token): ?object { return null; }
    public function limparTokenRecuperacaoSenha(string $uuid): void {}
    public function salvarTokenVerificacaoEmail(string $uuid, string $token): void {}
    public function buscarPorTokenVerificacaoEmail(string $token): ?object { return null; }
}
3

Registre no container em index.php

Este é o único lugar fora do módulo que precisa ser alterado — e só uma vez:

php
// index.php — substitua o binding de UserRepositoryInterface
$container->bind(
    \Src\Kernel\Contracts\UserRepositoryInterface::class,
    static fn() => new \Src\Modules\Cliente\Repositories\ClienteRepository(
        \Src\Kernel\Database\ModuleConnectionResolver::forModule('Cliente')
    ),
    true
);

A partir daí, Auth::user(), Auth::admin(), Auth::current() e todos os outros métodos funcionam automaticamente com a entidade Cliente.

Referência completa da fachada Auth

MétodoUsoDescrição
Auth::user()Middleware de rotaExige qualquer usuário logado
Auth::user(limit: 10)Middleware de rotaUsuário logado + rate limit 10/min
Auth::user(db: true)Middleware de rotaUsuário logado + circuit breaker
Auth::admin()Middleware de rotaExige admin_system
Auth::api()Middleware de rotaToken de API (machine-to-machine)
Auth::optional()Middleware de rotaAutenticação opcional
Auth::limit(5)Middleware de rotaSó rate limit, sem auth
Auth::db()Middleware de rotaSó circuit breaker
Auth::current($req)ControllerUsuário logado ou null
Auth::id($req)ControllerUUID do usuário ou null
Auth::role($req)ControllerNível de acesso ou null
Auth::check($req)ControllerRetorna usuário ou lança 401
Auth::checkAdmin($req)ControllerRetorna usuário ou lança 403
Auth::checkRole($req, 'admin')ControllerVerifica papel ou lança 403
O que Auth::current() retorna

Retorna um objeto que implementa AuthenticatableInterface com os métodos:
getAuthId() — ID único (UUID)
getAuthEmail() — e-mail
getAuthUsername() — username (pode ser null)
getAuthRole() — nível de acesso (ex: 'usuario', 'admin_system')
isAtivo() — se a conta está ativa
isEmailVerificado() — se o e-mail foi verificado