2015-04-10 6 views
13

Ich bin beeindruckt, wie einfach es war, eine REST-API in Yii2 zu erstellen. Allerdings habe ich ein kleines Problem, die Basic Authentication zu verstehen. Meine Bedürfnisse sind äußerst einfach und ich möchte, dass meine Lösung dem Beispiel folgt.Yii2 REST Simplify BasicAuth

Ich brauche hier grundlegende Token-Authentifizierung. Ich bin noch nicht einmal dagegen, es vorläufig zu kodieren, aber hier ist, was ich bisher gemacht habe.

Ich habe meine Datenbank-Tabelle Singular Token ApiAccess (id, access_token)

ApiAccess.php zu halten - Modell - Hinweis: IDE zeigt Syntaxfehler auf dieser ersten Zeile

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

Modul .php - in Funktion init()

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

I hat diese ApiContro ller, die jeweils nachfolgenden Nomen

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

erstreckt Wie es aussieht, ein api Endpunkt im Browser Zugriff auf aufgefordert, einen Benutzernamen und ein Passwort. Anfrage über REST-Client zeigt Zugriffsfehler an.

Wie binde ich HttpBasicAuth korrekt mit meinem ApiAccess-Modell?

ODER

Wie hart codieren ich einen api Zugriffstoken? (Erste Option ist offensichtlich am besten)

Antwort

21

Lassen Sie uns sehen und versuchen zu verstehen "yii" Weg grundlegende Auth für REST.

1. Wenn Sie Ihrem REST-Controller Verhalten hinzufügen, aktivieren Sie die grundlegende Authentifizierung:

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

Wie Sie getan haben. Was heißt das? Dies bedeutet, dass Ihre Anwendung den Autorisierungskopf analysiert. Es sieht so aus:

Authorization : Basic base64(user:password) 

Hier ist ein Trick für yii2. Wenn Sie Code jetzt genauer, sehen Sie, dass yii verwendet access_token von Benutzerfeld, so sollten Sie Ihre Header wie folgt aussehen:

Authorization : Basic base64(access_token:) 

Sie diesen Header, indem Sie Ihre eigenen analysieren kann, wenn Sie dieses Verhalten ändern möchten:

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

Zweite Sache zu tun. Sie müssen die Funktion findIdentityByAccessToken() von identityInterface implementieren. Warum beschweren sich Ihre IDE?

class User extends ActiveRecord implements IdentityInterface 

So sollte Ihre Benutzerklassendeklaration aussehen.

Von der Implementierung und Struktur:

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

Sie nicht Objekt der Klasse zurückkehren, die Identität Schnittstelle implementiert.

Wie man es richtig macht? Fügen Sie die Spalte access_token zu Ihrer Benutzertabelle hinzu und geben Sie Ihr Benutzermodell zurück (Sie können sehen, wie es hier aussehen muss - https://github.com/yiisoft/yii2-app-advanced/blob/master/common/models/User.php) Wenn Sie dies tun - Standardcode wird mit Ihrer findIdentityByAccessToken() Implementierung funktionieren.

Wenn Sie nicht Feld zu Benutzer Tabelle hinzufügen möchten - neue mit user_id,access_token Felder zu machen. Dann sollte Ihre Implementierung wie folgt aussehen:

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

Ich hoffe, ich könnte alle Ihre Fragen abdecken.

+0

Ich habe das funktioniert, und sehen, wie es jetzt funktionieren soll. Vielen Dank. Ich habe immer noch ein Problem im Zusammenhang mit der LDAP-Authentifizierung, die nur für dieses Modul vorhanden ist. Ich werde eine separate Frage stellen, wenn ich sie nicht alleine lösen kann. – Joshua

+0

Das findOne verschlüsselt das Passwort nicht, um zu sehen, ob es mit password_hash übereinstimmt - wie integriere ich validatePassword mit findOne? – Cymbals

+0

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