Middleware маршрути

Flight підтримує маршрути та групи маршрутів для проміжного програмного забезпечення. Проміжне програмне забезпечення — це функція, яка виконується перед (або після) зворотного виклику маршруту. Це чудовий спосіб додати перевірки автентифікації API у вашому коді або підтвердити, що користувач має дозвіл на доступ до маршруту.

Основне проміжне програмне забезпечення

Ось базовий приклад:

// Якщо ви надасте лише анонімну функцію, вона буде виконана перед зворотним викликом маршруту. 
// немає "після" функцій проміжного програмного забезпечення, крім класів (див. нижче)
Flight::route('/path', function() { echo ' Тут я!'; })->addMiddleware(function() {
    echo 'Проміжне програмне забезпечення першим!';
});

Flight::start();

// Це виведе "Проміжне програмне забезпечення першим! Тут я!"

Є кілька дуже важливих приміток про проміжне програмне забезпечення, про які вам слід знати, перш ніж їх використовувати:

  • Функції проміжного програмного забезпечення виконуються в порядку їх додавання до маршруту. Виконання подібне до того, як Slim Framework обробляє це.
    • Спочатку виконуються функції "перед", а потім "після" в зворотному порядку.
  • Якщо ваша функція проміжного програмного забезпечення повертає false, все виконання зупиняється, і виникає помилка 403 Заборонено. Вам, напевно, захочеться обробити це більш елегантно за допомогою Flight::redirect() або чогось подібного.
  • Якщо вам потрібні параметри з вашого маршруту, вони будуть передані в єдиному масиві вашій функції проміжного програмного забезпечення. (function($params) { ... } або public function before($params) {}). Причина в цьому полягає в тому, що ви можете структурувати свої параметри в групи, і в деяких з цих груп ваші параметри можуть насправді з'являтися в іншому порядку, що зламало б функцію проміжного програмного забезпечення, звертаючись до неправильного параметра. Таким чином, ви можете отримати до них доступ за ім'ям, а не за позицією.
  • Якщо ви передасте лише назву проміжного програмного забезпечення, вона автоматично буде виконана контейнером впровадження залежностей, а проміжне програмне забезпечення буде виконано з необхідними параметрами. Якщо у вас немає зареєстрованого контейнера впровадження залежностей, буде передано екземпляр flight\Engine у __construct().

Класи проміжного програмного забезпечення

Проміжне програмне забезпечення також може бути зареєстроване як клас. Якщо вам потрібен функціонал "після", ви повинні використовувати клас.

class MyMiddleware {
    public function before($params) {
        echo 'Проміжне програмне забезпечення першим!';
    }

    public function after($params) {
        echo 'Проміжне програмне забезпечення останнім!';
    }
}

$MyMiddleware = new MyMiddleware();
Flight::route('/path', function() { echo ' Тут я! '; })->addMiddleware($MyMiddleware); // також ->addMiddleware([ $MyMiddleware, $MyMiddleware2 ]);

Flight::start();

// Це виведе "Проміжне програмне забезпечення першим! Тут я! Проміжне програмне забезпечення останнім!"

Обробка помилок проміжного програмного забезпечення

Скажімо, у вас є проміжне програмне забезпечення для автентифікації, і ви хочете перенаправити користувача на сторінку входу, якщо він не автентифікований. У вас є кілька варіантів на вибір:

  1. Ви можете повернути false з функції проміжного програмного забезпечення, і Flight автоматично поверне помилку 403 Заборонено, але без кастомізації.
  2. Ви можете перенаправити користувача на сторінку входу за допомогою Flight::redirect().
  3. Ви можете створити власну помилку в межах проміжного програмного забезпечення та зупинити виконання маршруту.

Основний приклад

Ось простий приклад return false;:

class MyMiddleware {
    public function before($params) {
        if (isset($_SESSION['user']) === false) {
            return false;
        }

        // оскільки це правда, все продовжує йти далі
    }
}

Приклад перенаправлення

Ось приклад перенаправлення користувача на сторінку входу:

class MyMiddleware {
    public function before($params) {
        if (isset($_SESSION['user']) === false) {
            Flight::redirect('/login');
            exit;
        }
    }
}

Приклад користувацької помилки

Скажімо, вам потрібно викинути JSON-помилку, оскільки ви створюєте API. Ви можете зробити це ось так:

class MyMiddleware {
    public function before($params) {
        $authorization = Flight::request()->headers['Authorization'];
        if(empty($authorization)) {
            Flight::jsonHalt(['error' => 'Ви повинні бути увійшли, щоб отримати доступ до цієї сторінки.'], 403);
            // або
            Flight::json(['error' => 'Ви повинні бути увійшли, щоб отримати доступ до цієї сторінки.'], 403);
            exit;
            // або
            Flight::halt(403, json_encode(['error' => 'Ви повинні бути увійшли, щоб отримати доступ до цієї сторінки.']);
        }
    }
}

Групування проміжного програмного забезпечення

Ви можете додати групу маршрутів, і тоді кожен маршрут у цій групі матиме таке ж проміжне програмне забезпечення. Це корисно, якщо ви хочете групувати кілька маршрутів за, наприклад, проміжним програмним забезпеченням Auth, щоб перевірити ключ API в заголовку.


// додано в кінець методу групи
Flight::group('/api', function() {

    // Цей "порожній" виглядаючий маршрут насправді відповідатиме /api
    Flight::route('', function() { echo 'api'; }, false, 'api');
    // Це відповідатиме /api/users
    Flight::route('/users', function() { echo 'users'; }, false, 'users');
    // Це відповідатиме /api/users/1234
    Flight::route('/users/@id', function($id) { echo 'user:'.$id; }, false, 'user_view');
}, [ new ApiAuthMiddleware() ]);

Якщо ви хочете застосувати глобальне проміжне програмне забезпечення до всіх ваших маршрутів, ви можете додати "порожню" групу:


// додано в кінець методу групи
Flight::group('', function() {

    // Це все ще /users
    Flight::route('/users', function() { echo 'users'; }, false, 'users');
    // А це все ще /users/1234
    Flight::route('/users/@id', function($id) { echo 'user:'.$id; }, false, 'user_view');
}, [ new ApiAuthMiddleware() ]);