2017-03-17 31 views
1

我正在當角2/Yii2應用Yii2 + RESTAPI + CORS +承載方式 - 未授權創建自定義控制器動作

當我調用自定義控制器/動作從郵差與承載頭,一切正常,但是當我打電話它與角度爲2的應用程序(localhost:4200)的頭部相同,我始終得到未經授權的401錯誤。 當我做標準動作像例如從guide喜歡:

GET /users: list all users page by page; 
POST /users: create a new user; 

一切正常,只有當我創建的自定義操作,比我獲得授權。

這是交叉領域的應用, 角可以用web.example.com, yii2應用是srv.example.com

namespace app\controllers\restapi; 

use yii\filters\auth\CompositeAuth; 
use yii\filters\auth\HttpBearerAuth; 

class SearchOrderController extends \yii\rest\Controller 
{ 
    public $modelClass = 'app\models\Order'; 
    public function behaviors() 
    { 
     $behaviors = parent::behaviors(); 
     $auth = $behaviors['authenticator']; 
     unset($behaviors['authenticator']); 
     $behaviors['corsFilter'] = [ 
       'class' => \yii\filters\Cors::className(), 
     ]; 
     $behaviors['authenticator'] = [ 
       'class' => CompositeAuth::className(), 
       'authMethods' => [ 
         HttpBearerAuth::className(), 
       ], 
     ]; 
     // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method) 
     return $behaviors; 
    } 
    public function actionSearch(){ 
     \Yii::$app->response->format=\yii\web\Response::FORMAT_JSON; 
     return ['index'=>'some text', 'value'=>123]; 
    } 
} 

而且我的網址經理:

 [ 
      'class' => 'yii\rest\UrlRule', 
      'controller' => 'order', 
      'pluralize' => false, 
      'extraPatterns' => [ 
       'GET order/<id:\id+>' => 'order/view', 
      ] 
     ], 
     [ 
      'class' => 'yii\rest\UrlRule', 
      'controller' => 'search-order', 
      'pluralize' => false, 
      'extraPatterns' => [ 
       'GET search-order/search' => 'search-order/search', 
     ] 
+0

你確定GET和POST是失敗的請求嗎?你能否檢查你的瀏覽器的網絡標籤,看看它是不是一個'選項/用戶'失敗的? –

+0

這是選項......因爲我得到的消息是: 選項http://srv.example.com/restapi/search-order/search 401(未授權) 我該怎麼做? – stan

回答

0

我已經使用此處發佈的解決方案解決了我的問題:

Yii2 Rest - Custom action and OPTIONS method

,並實現自定義的一個Cors類:

<?php 
namespace app\components; 

use Yii; 
use yii\filters\Cors; 

class CustomCors extends Cors 

{ 
    public function beforeAction($action) 
    { 
     parent::beforeAction($action); 

     if (Yii::$app->getRequest()->getMethod() === 'OPTIONS') { 
      Yii::$app->getResponse()->getHeaders()->set('Allow', 'POST GET PUT'); 
      Yii::$app->end(); 
     } 

     return true; 
    } 
} 

,並相應地改變了我的控制行爲:

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

     // remove authentication filter 
     $auth = $behaviors['authenticator']; 
     unset($behaviors['authenticator']); 

     // add CORS filter 
     $behaviors['corsFilter'] = [ 
       'class' =>CustomCors::className() 
     ]; 

     // re-add authentication filter 
     $behaviors['authenticator'] = [ 
       'class' => CompositeAuth::className(), 
       'authMethods' => [ 
         HttpBearerAuth::className(), 
       ], 

     ]; 

     return $behaviors; 
    } 
0

它看起來是一個preflight request問題。我在這裏看到兩件事要解決。

首先,您需要實施一項操作以響應該請求,同時您正在擴展yii\rest\Controller。這種行動is already implemented by Yii但在其子控制器yii\rest\ActiveController。因此,無論您使用actions()功能導入它喜歡它是做here或者你可以直接實現它,因爲它是在這個其他satck溢出後完成:

Post Request working in Postman but returns Preflight error in Angular 2 app

然後,你需要定義自己的相關規定:

[ 
    'class' => 'yii\rest\UrlRule', 
    'controller' => 'order', 
    'pluralize' => false, 
    'extraPatterns' => [ 
     'GET order/<id:\id+>' => 'order/view', 
     'OPTIONS order/<id:\id+>' => 'order/options', 
    ] 
], 
[ 
    'class' => 'yii\rest\UrlRule', 
    'controller' => 'search-order', 
    'pluralize' => false, 
    'extraPatterns' => [ 
     'GET search-order/search' => 'search-order/search', 
     'OPTIONS search-order/search' => 'search-order/options', 
] 

下一步,你需要讓你的認證,允許預檢要求瀏覽器會不會與他們發送任何標記。通過添加此行如下所示official docs

// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method) 
$behaviors['authenticator']['except'] = ['options'];