2015-04-10 4 views
13

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

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

У меня есть таблица базы данных, чтобы держать свою особую символическую ApiAccess (идентификатор, 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]); 
    } 
} 

модуля .php - в функции инициализации()

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

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

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; 
    } 
} 

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

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

ИЛИ

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

ответ

21

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

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

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

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

Authorization : Basic base64(user:password) 

Вот трюк для yii2. Если вы посмотрите на код более внимательно, вы увидите, что юй использует 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().

Если вы не хотите добавлять поля в таблицу пользователей - создайте новый с полями 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]); 
    } 

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

+0

У меня есть эта работа, и посмотреть, как она должна работать сейчас. Спасибо. У меня все еще есть проблема, связанная с переопределением аутентификации LDAP уже на месте только для этого модуля. Я отправлю отдельный вопрос, если не могу решить его самостоятельно. – Joshua

+0

FindOne не шифрует пароль, чтобы узнать, соответствует ли он паролю password_hash - как включить validatePassword с findOne? – Cymbals

+0

@Cymbals http://www.yiiframework.com/doc-2.0/guide-security-passwords.html –