2015-04-10 14 views
13

Sono impressionato da quanto sia stato semplice creare una API REST in Yii2. Tuttavia, ho qualche problema a capire l'autenticazione di base. Le mie esigenze sono assolutamente semplici e vorrei che la mia soluzione seguisse l'esempio.RIPOSO Yii2 Semplifica BasicAuth

Ho bisogno dell'autenticazione token di base qui. Per ora non sono nemmeno contro la codifica, ma ecco cosa ho fatto fino ad ora.

devo tabella del database di tenere il mio ApiAccess gettone singolare (id, access_token)

ApiAccess.php - Modello - NOTA: IDE mostra errore di sintassi in questa prima linea

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

Module .php - in funzione init()

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

ho fatto un ApiContro ller che ogni successiva sostantivo estende

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

Così com'è, l'accesso a un endpoint api nel browser richiede un nome utente e una password. Richiesta tramite client REST visualizza errore di accesso.

Come legare correttamente HttpBasicAuth al modello ApiAccess?

O

Come posso hardcode un token di accesso api? (La prima opzione è ovviamente la migliore)

risposta

21

Guardiamo e proviamo a capire l'autenticazione di base "yii" per REST.

1 °. Quando si aggiunge un comportamento al controller REST, consentendo autenticazione di base:

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

volta che avete fatto. Cosa significa? Significa che la tua applicazione analizzerà la tua intestazione di autorizzazione. Sembra:

Authorization : Basic base64(user:password) 

Ecco un trucco per yii2. Se si guarda il codice più attentamente, vedrete che Yii utilizza access_token dal campo utente, quindi l'intestazione dovrebbe assomigliare:

Authorization : Basic base64(access_token:) 

È possibile analizzare questo colpo di testa da soli, se si desidera modificare questo comportamento:

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

Seconda cosa da fare. È necessario implementare la funzione findIdentityByAccessToken() da identityInterface. Perché il tuo IDE si lamenta?

class User extends ActiveRecord implements IdentityInterface 

Ecco come dovrebbe apparire la dichiarazione della classe utente.

Da l'implementazione e la struttura:

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

non ritorno oggetto della classe che implementa l'interfaccia identità.

Come farlo correttamente? Aggiungi colonna access_token alla tabella utenti e restituisci il modello utente (puoi vedere come deve apparire qui - https://github.com/yiisoft/yii2-app-advanced/blob/master/common/models/User.php) Se lo fai, il codice predefinito funzionerà con l'implementazione findIdentityByAccessToken().

Se non si desidera aggiungere un campo alla tabella utenti, crearne uno nuovo con i campi user_id,access_token. Quindi la tua implementazione dovrebbe essere simile a:

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

Spero di poter coprire tutte le tue domande.

+0

Ho questo funzionamento, e vedere come dovrebbe funzionare ora. Grazie. Ho ancora un problema relativo all'override dell'autenticazione LDAP già presente solo per questo modulo. Pubblicherò una domanda a parte se non riesco a risolverlo da solo. – Joshua

+0

Il findOne non crittografa la password per vedere se corrisponde a password_hash - come faccio a incorporare validatePassword con findOne? – Cymbals

+0

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