Я впечатлен тем, насколько просто было создать REST api в Yii2. Тем не менее, я немного затрудняюсь понять базовую аутентификацию. Мои потребности совершенно просты, и я бы хотел, чтобы мое решение последовало их примеру.
Мне нужна базовая аутентификация маркера. На данный момент я даже не против hardcoding, но вот что я сделал до сих пор.
У меня есть таблица базы данных для хранения моего единственного токена ApiAccess (id, access_token)
ApiAccess.php – Модель – ПРИМЕЧАНИЕ. 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? (Первый вариант, очевидно, лучше всего)
Давайте посмотрим и попытаемся понять «yii» путь базового auth для REST.
Первый. Когда вы добавляете поведение к контроллеру REST, вы включаете базовый auth:
$behaviors['authenticator'] = [ 'class' => HttpBasicAuth::className(), ];
Как и вы. Что это значит? Это означает, что ваше приложение будет анализировать ваш заголовок авторизации. Это выглядит как:
Authorization : Basic base64(user:password)
Вот трюк для yii2. Если вы внимательно посмотрите на код, вы увидите, что access_token
использует 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]); }
Вторая вещь. Вы должны реализовать 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]); }
Надеюсь, я смогу охватить все ваши вопросы.