Ответ переопределения аутентификации Rest (HttpBearerAuth) в yii2 - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть авторизация на основе токена, для которой я внес изменения ниже.

В Пользователь * Модель 1004 *, переопределите метод findIdentityByAccessToken(), как показано ниже.

public static function findIdentityByAccessToken($token, $type = null)
{
  $userlogin = Userdevices::find()->where(['access_token' => $token])->one();

  if ($userlogin == array()) {
      return null;
  } else {
      $User = Users::findOne(['id' => $userlogin->user_id]);
      if (!count($User))
      {
          return null;
      }
      else {
          $dbUser = [
              'id' => $User->id,
          ];
          return new static($dbUser);
      }
  }
}

В Контроллере я добавляю behaviors(), как показано ниже.

public function behaviors()
{
    $behaviors[] = [
        'class' => \yii\filters\ContentNegotiator::className(),
        'formats' => [
            'application/json' => \yii\web\Response::FORMAT_JSON,
        ],
    ];

    $behaviors['authenticator'] = [
        'class' => HttpBearerAuth::className(),
    ];

    return $behaviors;
}

Когда API не получает токен или токен недействителен, он выдает ниже ответ

{
    "name": "Unauthorized",
    "message": "You are requesting with an invalid credential.",
    "code": 0,
    "status": 401,
    "type": "yii\\web\\UnauthorizedHttpException"
}

Я хочу изменить ответ каксогласно моему требованию как ниже.

{
    "code": 401,
    "name": "Unauthorized",
    "is_logout": "Y",
    "status": "error",
    "message": "logout"
}

1 Ответ

1 голос
/ 04 ноября 2019

Вы можете изменить формат ответа, используя beforeSend событие yii\web\Response.

Например, добавьте следующие методы в ваш контроллер API:

public function init()
{
    parent::init();

    \Yii::$app->response->on(
        \yii\web\Response::EVENT_BEFORE_SEND,
        [$this, 'beforeResponseSend']
    );
}

public function beforeResponseSend(\yii\base\Event $event)
{
    /**
     * @var \yii\web\Response $response
     */
    $response = $event->sender;
    if ($response->data['status'] == 401) {
        $response->data = [
            'code' =>  401,
            'name' => 'Unauthorized',
            'is_logout' => 'Y',
            'status' => 'error',
            'message' => 'logout',
        ];
    }
}

Метод initконтроллер регистрирует событие beforeSend. Метод beforeResponseSend обрабатывает событие и изменяет формат ответа.

Если вы хотите отформатировать ответ в нескольких контроллерах, может быть лучше поместить обработчик событий в собственный класс, например

namespace app\components;

class ErrorResponseHelper
{
    public static function beforeResponseSend(Event $event)
    {
        // ... formating code ...
    }
}

И зарегистрируйте событие в config/web.php

return [
    // ...
    'components' => [
        'response' => [
            'class' => 'yii\web\Response',
            'on beforeSend' => [
                \app\components\ErrorResponseHelper::class,
                'beforeResponseSend',
            ],
        ],
    ],
];     

Но будьте осторожны с этим решением, потому что таким образом \app\components\ErrorResponseHelper::beforeResponseSend будет вызываться при каждом запросе.

...