2017-01-23 1 views
9

Am angular2 mit und yii2 geruhsamen Dienste aber es funktioniert nichtden Träger Token in yii2 Rest Passing gibt einen Fehler von 401

Das ist mein angular2 Teil

In the userservice 
constructor(private http:HttpClientService, private _domaindetails:Domaindetails) { } 

profile(val:string="profile"):Observable<User>{ 
return this.http.get(this.getUserUrl(val)) 
    .map(this.extractData) 

} 

Dies ist der httpclientService

createAuthorizationHeader(headers: Headers) { 
    let token = JSON.parse(localStorage.getItem("currentUser")).token; 
    if (token) { 
    headers.append('Authorization', 'Bearer ' + token); 
    headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
    headers.append('Content-Type', 'application/json'); 
    } 

    } 

post(url, data) { 
    let headers = new Headers(); 
    this.createAuthorizationHeader(headers); 
return this.http.post(url, data, { 
    headers: headers 
}); 
} 

Dies ist mein Backend In Yii2

public function behaviors() 
{ 
    $behaviors = parent::behaviors(); 
    $behaviors['corsFilter'] = [ 
     'class' => \yii\filters\Cors::className(), 
     'cors' => [ 
      // restrict access to 
      'Origin' => ['http://localhost:4200'], 
      'Access-Control-Request-Method' => ['POST', 'GET','PUT'], 
      // Allow only POST and PUT methods 
      'Access-Control-Request-Headers' => ['*'], 
      // Allow only headers 'X-Wsse' 
      // 'Access-Control-Allow-Credentials' => true, 
      // Allow OPTIONS caching 
      'Access-Control-Max-Age' => 3600, 
      // Allow the X-Pagination-Current-Page header to be exposed to the browser. 
      'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'], 
     ], 
    ]; 

    $auth = $behaviors['authenticator'] = [ 
     'class' => HttpBearerAuth::className(), 
     'only' => ['can-access','profile'], //access controller 
    ]; 

    $behaviors['authenticator']['except'] = ['options']; 
    return $behaviors; 
} 

Und die yii2 Aktion fehlschlägt einen Fehler von unerlaubten Zugriff Rückkehr

public function actionProfile() 
{ 

    $user = Yii::$app->user->identity; 
    return ['data' => $user]; 
} 

Wenn ich überprüfen Yii::$app->request->headers;

enter image description here

Wie Sie der Inhaber Token

gesetzt sehen

Dieses usermodel meine ist

public static function findIdentityByAccessToken($token, $type = null) 
{ 
    return static::findOne(['auth_key' => $token]); //auth_key is the value used in bearer token 
} 

Warum es einem Fehler 401 nicht autorisierten Zugriff auf Rückkehr und noch nicht halten, wenn ich den gleichen Wert von authkey und stellen Berechtigungsinhaber Header in Postbote verwenden funktioniert es

Nach einiger Forschung fand ich heraus, dass das, wenn angular2 eine Anfrage macht sendet er eine Optionsanfrage, die

+0

Haben Sie versucht, das Verhalten auf "bearerAuth" anstelle von "authenticator" zu setzen? – kyle

+0

Das schlägt auch fehl und gibt unbekanntes bearerAuth zurück –

Antwort

1

Für diejenigen nicht, die mit diesem Problem konfrontiert könnte ich das herausfand, dies durch die HttpBearerAuth verursacht wurde, und wenn ich zu QueryParamAuth alles verändert arbeitet jetzt habe ich auch noch ein paar andere Änderungen als

ON THE CONTROLLER 
1.Removed the cors filters 

public function behaviors() 
{ 
    $behaviors = parent::behaviors(); 

    $behaviors['authenticator'] = [ 
     'class' => CompositeAuth::className(), 
     'authMethods' => [ 
      HttpBasicAuth::className(), 
      HttpBearerAuth::className(), 
      QueryParamAuth::className(), 
     ], 
    ]; 
    return $behaviors; 

} 
gemacht

2, In meiner co nfig main.php

 'response' => [ 
     'format' => yii\web\Response::FORMAT_JSON, 
     'charset' => 'UTF-8', 
     'on beforeSend' => function ($event) { 
      header("Access-Control-Allow-Origin: *"); 
     } 
    ], 
     'urlManager' => [ 
     'class' => 'yii\web\UrlManager', 
     'enablePrettyUrl' => true, 
     'showScriptName' => false, 
     'rules' => [ 
      ['class' => 'yii\rest\UrlRule', 'controller' => 'auth', 'pluralize'=>false], 
      ...other controlers here 
     ], 

    ], 

3.In der .htacess Datei im Root-Projekt i

hinzugefügt
Header set Access-Control-Allow-Origin "*" 
    Header set Access-Control-Allow-Headers "Content-Type" 

So Anfrage meiner angular2 Post sieht aus wie

http://127.0.0.1/bcl/api/rest/v1/auth/logout?access-token=your access token 

So ist die Token-Zugriff ist immer als Abfrageparameter übergeben

Der Hauptgrund ist, weil ich herausgefunden habe, dass, wenn der Browser sen ds jeder Header abgesehen von Inhaltstyp ein Options Anfrage

So ausgelöst wird jetzt meine Header aussehen

headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
//i removed the bearer token 
1

ich einen anderen Ansatz verwendet:

Added

public function beforeAction($action) 
    { 
     $this->enableCsrfValidation = false; 
     parent::beforeAction($action); 

     if (Yii::$app->getRequest()->getMethod() === 'OPTIONS') { 
      // End it, otherwise a 401 will be shown. 
      Yii::$app->end(); 
     } 

     return true; 
    } 

in der Steuerung .

Behalten Sie die Verhaltensfunktion wie bei Ihrer Frage.

Wie Sie bereits erwähnt haben, sendet der Browser eine Preflight-Anfrage.

Meine Annahme ist, dass Sie eine Cross-Browser-Anfrage machen (localhost: 4200), also macht der Browser zuerst eine OPTIONS-Anfrage an den Server, um die "Access-Control-Allow" -Einstellungen herauszufinden, aber ohne Zugriff Token in der Kopfzeile. So wird eine 401 geworfen und der CORS-Prozess wird unterbrochen.

Der Unterschied ist, dass Sie auf diese Weise das Berechtigungstoken in einer Kopfzeile haben können.

+0

Ich versuchte Ihre Methode, aber scheitert, ich denke, dass die Verhaltensweisen zuerst ausgeführt werden, sogar die beforeAction –

+0

Versuchen Sie, 'Origin' => ['*'] im Verhalten() zu setzen, um alle Hosts zuzulassen. Ich sehe, du hast das selbe in deiner Lösung innerhalb der Config gemacht. Auf jeden Fall sollte dies mit dem eckigen Host übereinstimmen. –

Verwandte Themen