O Flight suporta middleware de rota e de grupo de rotas. O middleware é uma função que é executada antes (ou depois) do retorno da rota. Esta é uma ótima maneira de adicionar verificações de autenticação da API em seu código, ou para validar se o usuário tem permissão para acessar a rota.
Aqui está um exemplo básico:
// Se você fornecer apenas uma função anônima, ela será executada antes do retorno da rota. // não existem funções de middleware "after" exceto para classes (veja abaixo) Flight::route('/caminho', function() { echo ' Aqui estou!'; })->addMiddleware(function() { echo 'Middleware primeiro!'; }); Flight::start(); // Isso irá produzir "Middleware primeiro! Aqui estou!"
Existem algumas notas muito importantes sobre middleware que você deve ter em mente antes de usá-los:
Flight::redirect()
function($params) { ... }
public function before($params) {}
flight\Engine
__construct()
O middleware pode ser registrado como uma classe também. Se você precisa da funcionalidade "after", você deve usar uma classe.
class MeuMiddleware { public function before($params) { echo 'Middleware primeiro!'; } public function after($params) { echo 'Middleware último!'; } } $MeuMiddleware = new MeuMiddleware(); Flight::route('/caminho', function() { echo ' Aqui estou! '; })->addMiddleware($MeuMiddleware); // também ->addMiddleware([ $MeuMiddleware, $MeuMiddleware2 ]); Flight::start(); // Isso irá exibir "Middleware primeiro! Aqui estou! Middleware último!"
Digamos que você tenha um middleware de autenticação e deseje redirecionar o usuário para uma página de login se ele não estiver autenticado. Você tem algumas opções à sua disposição:
Aqui está um exemplo simples de retorno falso:
class MeuMiddleware { public function before($params) { if (isset($_SESSION['user']) === false) { return false; } // como é verdadeiro, tudo continua normalmente } }
Aqui está um exemplo de redirecionamento do usuário para uma página de login:
class MeuMiddleware { public function before($params) { if (isset($_SESSION['user']) === false) { Flight::redirect('/login'); exit; } } }
Digamos que você precise lançar um erro JSON porque está construindo uma API. Você pode fazer isso assim:
class MeuMiddleware { public function before($params) { $autorizacao = Flight::request()->headers['Authorization']; if(empty($autorizacao)) { Flight::jsonHalt(['error' => 'Você deve estar logado para acessar esta página.'], 403); // ou Flight::json(['error' => 'Você deve estar logado para acessar esta página.'], 403); exit; // ou Flight::halt(403, json_encode(['error' => 'Você deve estar logado para acessar esta página.']); } } }
Você pode adicionar um grupo de rota e, em seguida, cada rota nesse grupo terá o mesmo middleware também. Isso é útil se você precisar agrupar um monte de rotas, digamos por um middleware de Autenticação para verificar a chave da API no cabeçalho.
// adicionado no final do método de grupo Flight::group('/api', function() { // Esta rota com aparência "vazia" na verdade corresponderá a /api Flight::route('', function() { echo 'api'; }, false, 'api'); // Esta corresponderá a /api/usuarios Flight::route('/usuarios', function() { echo 'usuários'; }, false, 'usuários'); // Esta corresponderá a /api/usuarios/1234 Flight::route('/usuarios/@id', function($id) { echo 'usuário:'.$id; }, false, 'visualização_de_usuario'); }, [ new MiddlewaredeAutenticacaoApi() ]);
Se você deseja aplicar um middleware global a todas as suas rotas, pode adicionar um grupo "vazio":
// adicionado no final do método de grupo Flight::group('', function() { // Isto ainda é /usuários Flight::route('/usuários', function() { echo 'usuários'; }, false, 'usuários'); // E isto ainda é /usuários/1234 Flight::route('/usuários/@id', function($id) { echo 'usuário:'.$id; }, false, 'visualização_de_usuario'); }, [ new MiddlewaredeAutenticacaoApi() ]);