another_dream
@another_dream
Backend-разработчик, Laravel/ZF2/Yii2

Как реализовать middleware-like логику в Yii2?

Реализуем API для клиента, авторизация по токену, то есть параметром в GET (или в заголовках) приходит параметр token, который используется для идентификации пользователя и предоставления данных к ресурсам платформы.

Есть общий контроллер, от которого наследуются все остальные (AuthController, ProductController, OrdersController и прочие). Хотелось бы в этом контроллере описать логику для проверки наличия токена (в идеале свой метод описать, может быть где-то указать этот метод коллбэком, например) и при наличии оного - пускать запрос на дальнейшее выполнение, в ином случае - возвращать JSON объект с необходимыми мне данными. Данные действия должны проводиться при каждом запросе, то есть как в случае с Middleware, например, в Laravel.

Метод beforeAction в контроллере решает задачу наполовину - я могу вернуть false и тогда выполнение просто прерывается, мне же необходимо выдать хоть какую-то информацию клиенту, например сообщение, в формате JSON, об отсутствии токена и, возможно, еще некоторыми данными.

Реализация Component объекта и подключение оного в bootstrap раздел конфига приложения - аналогично beforeAction.

Если верну что-то кроме false или исключения, то ответ принимается как true и выполнение продолжается.
  • Вопрос задан
  • 3782 просмотра
Решения вопроса 1
DieZz
@DieZz
Используйте поведения (behaviors). Например в Yii из коробки есть такая штука:
public function behaviors()
{
    $behaviors = parent::behaviors();
    $behaviors['authenticator'] = [
        'class' => HttpBearerAuth::className(),
    ];
    
    return $behaviors;
}


Если хотите свою логику для проверки токена, то создайте класс который будет имлпементировать интерфейс yii\filters\auth\AuthInterface у указывайте его в поведении. В случае ошибки авторизации бросайте UnauthorizedHttpException
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
another_dream
@another_dream Автор вопроса
Backend-разработчик, Laravel/ZF2/Yii2
Появилась идея, переопределить метод runAction:
public function runAction($id, $params = [])
    {
        \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        // Если условие истино, то выкидываю ошибку
        if (mt_rand(0,1) === 0) {
            return [
                   'status' => false,
                   'errors' => 'Ошибка'
            ];
        } else {
        // Иначе продолжаем выполнение
            parent::runAction($id, $params);
        }
    }

Работает как требуется, какие могут быть подводные камни? Рационально/разумно ли такое решение?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы