Статьи

OAuth Middleware для Slim

OAuth может быть любым, каким вы хотите, стандарты слабы и дают вам много места для правильной реализации вашей системы. Однако, как бы вы ни продолжали, вам нужно проверять токен доступа при каждом запросе — и в приложении Slim промежуточное ПО может оказать огромную помощь, так как оно подключается к каждому запросу. Я недавно реализовал это и думал, что поделюсь.

Получение токена доступа

Это RPC-esque API, и есть действие, которое очень похоже на метод входа пользователя. В терминах OAuth это «поток учетных данных клиента». Поскольку потребитель этого API создается той же организацией, что и сам API, между ними существует высокая степень доверия. Чтобы упростить задачу, потребитель запрашивает у пользователя его учетные данные и передает их в API (примечание: потребитель не сохраняет их и никогда больше их не использует. Приложение доверенного потребителя — это ЕДИНСТВЕННОЕ время, когда вы предоставляете свой пароль). любой третьей стороне). API проверяет их и отправляет обратно токен доступа, который потребитель затем использует для всех будущих запросов.

Это базовый тип входа в систему, похожий на тот, который вы бы использовали на любом веб-сайте, а маркер доступа — это просто сгенерированный хэш какого-либо типа. Вы можете сделать что угодно здесь, сгенерировать что-то и затем сохранить это, чтобы позже вы могли снова привязать его к нужному пользователю. Для записи мой код выглядит так:

    $token = bin2hex(openssl_random_pseudo_bytes(16));

Затем потребитель захватывает этот токен и добавляет его в заголовок авторизации всех будущих запросов, так что заголовок выглядит так:

Authorisation: OAuth [token]

Проверка токена

Теперь нам нужно проверять токен при каждом запросе, где мы ожидаем, что пользователь будет аутентифицирован. Вы можете сделать это с проверкой в ​​верхней части каждого соответствующего действия контроллера, но Slim имеет механизм, который делает это еще проще: его промежуточное программное обеспечение предоставляет хуки, которые можно использовать при каждом запросе.

Middleware — это отдельный класс, вот мой:

namespace MyLib\Middleware;

class OAuth2Auth extends \Slim\Middleware
{
    protected $headers = array();

    protected $config;

    protected $mysql; // PDO

    public function __construct($headers, $config, $mysql) {
        $this->headers = $headers;
        $this->config = $config;
        $this->mysql = $mysql;
    }

    public function call() {
        // no auth header
        if(!isset($this->headers['Authorization'])) {
            $this->app->getLog()->error("No authorization header");
            $view = $this->app->view();
            $view->setData("data", array("message" => "Access credentials not supplied"));
            $view->render('error.php', 400);
        } else {
             try {
                $authHeader = $this->headers['Authorization'];
                $auth = new \Service\Mysql\AuthService($this->mysql, $this->config);
                $validated_user_id = $auth->verifyOAuth($authHeader);
                $this->app->user_id = $validated_user_id;
             } catch (\Exception $e) {
                $view = $this->app->view();
                $view->setData("data", array("message" => $e->getMessage()));
                $view->render('error.php', $e->getCode());
             }
           }

        // this line is required for the application to proceed
        $this->next->call();
    }
}

Надеемся, что этот код достаточно прост, чтобы следовать, конструктор этого класса принимает некоторые зависимости, включая входящие заголовки для этого запроса. Затем call()метод вызывается, когда наступает очередь этого промежуточного программного обеспечения … и в конце этого метода мы вызываем следующее промежуточное программное обеспечение в списке. В рамках этого основного метода мы проверяем входящий заголовок в базе данных и сохраняем информацию о пользователе, чтобы мы могли использовать ее снова, если мы хотим использовать их идентификационные данные при дальнейшей обработке детали этого запроса. Это приложение требует, чтобы все запросы были аутентифицированы, но если ваш разрешает некоторый неаутентифицированный доступ, вы также можете просто не устанавливать данные пользователя и продолжить — тогда проверьте, присутствуют ли эти данные в соответствии с каждым маршрутом.

Добавление Middleware в Slim Framework

Я обнаружил, что это очень простой способ заставить один и тот же код срабатывать при каждом запросе, ничего не помня 🙂 Он настраивается после того, как я создал экземпляр приложения (которое находится в нем $app) и подключен к базе данных (объект PDO хранится в $ MySQL). Затем index.phpя просто добавляю эти строки:

// Add OAuth middleware
$headers = apache_request_headers();
$app->add(new \MyLib\Middleware\OAuth2Auth($headers, $config, $mysql));

Надеюсь, если вам нужно реализовать что-то подобное, это даст вам представление о том, какой шаблон вы можете использовать. Дополнительные советы, вопросы или комментарии приветствуются, просто используйте форму комментария ниже 🙂