Подтвердить что ты не робот

Yii2 REST Упростить BasicAuth

Я впечатлен тем, насколько просто было создать REST api в Yii2. Тем не менее, я немного затрудняюсь понять базовую аутентификацию. Мои потребности совершенно просты, и я бы хотел, чтобы мое решение последовало примеру.

Мне нужна базовая аутентификация маркера. На данный момент я даже не против жесткого кодирования, но вот что я сделал до сих пор.

У меня есть таблица базы данных для хранения моего единственного токена ApiAccess (id, access_token)

ApiAccess.php - Model - ПРИМЕЧАНИЕ. IDE показывает синтаксическую ошибку в этой первой строке

 class ApiAccess extends base\ApiAccessBase implements IdentityInterface
 {
   public static function findIdentityByAccessToken($token, $type = null)
   {
     return static::findOne(['access_token' => $token]);
   }
 }

Module.php - в функции init()

 \Yii::$app->user->enableSession = false;

Я сделал ApiController, что каждое последующее существительное расширяет

ApiController.php

 use yii\rest\ActiveController;
 use yii\filters\auth\HttpBasicAuth;
 use app\models\db\ApiAccess;

 class ApiController extends ActiveController
 {
   public function behaviors()
   {
      $behaviors = parent::behaviors();
      $behaviors['authenticator'] = [
        'class' => HttpBasicAuth::className(),
      ];
     return $behaviors;
   }
 }

Как бы то ни было, доступ к конечной точке api в браузере запрашивает имя пользователя и пароль. Запрос через REST Client отображает ошибку доступа.

Как правильно привязать HttpBasicAuth к моей модели ApiAccess?

ИЛИ

Как я могу жестко указать токен доступа api? (первый вариант, очевидно, лучше всего)

4b9b3361

Ответ 1

Давайте посмотрим и попытаемся понять "yii" путь базового auth для REST.

первый. Когда вы добавляете поведение к вашему контроллеру REST, вы включаете базовое auth:

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

Как и вы. Что это значит? Это означает, что ваше приложение будет анализировать ваш заголовок авторизации. Это выглядит так:

Authorization : Basic base64(user:password)

Вот трюк для yii2. Если вы посмотрите внимательно на код, вы увидите, что yii использует access_token из поля пользователя, поэтому ваш заголовок должен выглядеть так:

Authorization : Basic base64(access_token:)

Вы можете проанализировать этот заголовок самостоятельно, если вы хотите изменить это поведение:

$behaviors['authenticator'] = [
            'class' => HttpBasicAuth::className(),
            'auth' => [$this, 'auth']
        ];
....
public function auth($username, $password)
    {
        return \app\models\User::findOne(['login' => $username, 'password' => $password]);
    }

2-я вещь. Вы должны реализовать функцию findIdentityByAccessToken() от identityInterface. Почему ваша IDE жалуется?

class User extends ActiveRecord implements IdentityInterface

Вот как выглядит ваше объявление класса пользователя.

Из вашей реализации и структуры:

public static function findIdentityByAccessToken($token, $type = null)
   {
     return static::findOne(['access_token' => $token]);
   }

вы не возвращаете объект класса, который реализует интерфейс идентификации.

Как сделать это правильно? Добавьте столбец access_token в таблицу ваших пользователей и верните свою пользовательскую модель (вы можете посмотреть, как она должна выглядеть здесь - https://github.com/yiisoft/yii2-app-advanced/blob/master/common/models/User.php) Если вы это сделаете - код по умолчанию будет работать с вашей реализацией findIdentityByAccessToken().

Если вы не хотите добавлять поля в таблицу users - создайте новый с полями user_id,access_token. Тогда ваша реализация должна выглядеть так:

public static function findIdentityByAccessToken($token, $type = null)
   {
     $apiUser = ApiAccess::find()
        ->where(['access_token' => $token])
        ->one();
     return static::findOne(['id' => $apiUser->user_id, 'status' => self::STATUS_ACTIVE]);
   }

Надеюсь, что смогу ответить на все ваши вопросы.