2016-02-12 22 views
5

Tôi đã phát triển dịch vụ REST Angular & Yii2 REST. Có vấn đề trong miền chéo. Dưới đây, hãy thêm mã số & Yii2 REST góc cạnh của tôi.Yii2 REST + Tên miền chéo góc CORS

AngularJs: (như 'http://organization1.example.com', 'http://organization2.example.com', ....)

$http.defaults.useXDomain = true; 
$http.defaults.withCredentials = true; 
$http.defaults.headers.common['Authorization'] = 'Bearer ' + MYTOKEN 

Yêu cầu của tôi từ điều khiển góc:

apiURL = 'http://api.example.com'; 
$http.get(apiURL + '/roles') 
    .success(function (roles) { }) 
    .error(function() { }); 

Yii2 .htaccess: (REST URL như ' http://api.example.com ')

Header always set Access-Control-Allow-Origin: "*" 
Header always set Access-Control-Allow-Credentials: true 
Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS" 
Header always set Access-Control-Allow-Headers "Authorization,X-Requested-With, content-type" 

Yii2 Hành vi của tôi:

public function behaviors() { 
    $behaviors = parent::behaviors(); 
    $behaviors['corsFilter'] = [ 
     'class' => Cors::className(), 
     'cors' => [ 
      'Origin' => ['*'], 
      'Access-Control-Expose-Headers' => [ 
       'X-Pagination-Per-Page', 
       'X-Pagination-Total-Count', 
       'X-Pagination-Current-Page', 
       'X-Pagination-Page-Count', 
      ], 
     ], 
    ]; 
    $behaviors['authenticator'] = [ 
     'class' => HttpBearerAuth::className(), 
     'except' => ['options'], 
    ]; 
    $behaviors['contentNegotiator'] = [ 
     'class' => ContentNegotiator::className(), 
     'formats' => [ 
      'application/json' => Response::FORMAT_JSON, 
     ], 
    ]; 

    return $behaviors; 
} 

Vấn đề

Từ yêu cầu góc của tôi là 'GET' phương pháp, nhưng nó sẽ đi phương pháp 'Options' & trở lại 401 lỗi trái phép (CORS). vì yêu cầu Tiêu đề cấp phép không được gửi.

Trả lời

0

Trong điều khiển của bạn:

use yii\filters\Cors; 
... 
public function behaviors() 
{ 
    return array_merge([ 
     'cors' => [ 
      'class' => Cors::className(), 
      #special rules for particular action 
      'actions' => [ 
       'your-action-name' => [ 
        #web-servers which you alllow cross-domain access 
        'Origin' => ['*'], 
        'Access-Control-Request-Method' => ['POST'], 
        'Access-Control-Request-Headers' => ['*'], 
        'Access-Control-Allow-Credentials' => null, 
        'Access-Control-Max-Age' => 86400, 
        'Access-Control-Expose-Headers' => [], 
       ] 
      ], 
      #common rules 
      'cors' => [ 
       'Origin' => [], 
       'Access-Control-Request-Method' => [], 
       'Access-Control-Request-Headers' => [], 
       'Access-Control-Allow-Credentials' => null, 
       'Access-Control-Max-Age' => 0, 
       'Access-Control-Expose-Headers' => [], 
      ] 
     ], 
    ], parent::behaviors()); 
} 

Documentation

7

Cập nhật:

Như đã chỉ bởi @jlapoutre, điều này hiện nay cũng được mô tả in official docs:

Thêm Cross -bộ lọc chia sẻ tài nguyên gốc bộ điều khiển phức tạp hơn so với các bộ lọc khác được mô tả ở trên, vì bộ lọc CORS phải được áp dụng trước khi xác thực phương pháp và do đó cần cách tiếp cận hơi khác so với các bộ lọc khác. Ngoài ra xác thực phải được vô hiệu hóa cho CORS Preflight yêu cầu để trình duyệt có thể xác định một cách an toàn liệu yêu cầu có thể được thực hiện trước mà không cần gửi xác thực thông tin xác thực hay không. Sau đây cho thấy các mã đó là cần thiết để thêm yii \ lọc \ CORS lọc để một bộ điều khiển hiện có mà kéo dài từ yii \ còn lại \ ActiveController:

use yii\filters\auth\HttpBasicAuth; 

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

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

    // add CORS filter 
    $behaviors['corsFilter'] = [ 
     'class' => \yii\filters\Cors::className(), 
    ]; 

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

    return $behaviors; 
} 

Old trả lời(không được chấp nhận)

Có sự cố đặt hàng khi hợp nhất với parent::behaviors(). Chi tiết đầy đủ here.

tôi khuyên bạn không xác định phím khi sáp nhập với mảng mẹ:

public function behaviors() 
{ 
    return \yii\helpers\ArrayHelper::merge([ 
     [ 
      'class' => \yii\filters\Cors::className(), 
      'cors' => [...], 
     ], 
     [ 
      'class' => \yii\filters\auth\HttpBearerAuth::className(), 
      'except' => ['options'], 
     ], 
     [ 
      'class' => ContentNegotiator::className(), 
      'formats' => [...], 
     ] 
    ], parent::behaviors()); 
} 
+1

này bây giờ được ghi chép rõ ràng ở đây: http://www.yiiframework.com/doc-2.0/guide-rest-controllers.html # cors - chỉ cần làm theo hướng dẫn này và nó sẽ hoạt động. Tóm tắt: đảm bảo xác thực đến sau hành vi CORS và loại trừ OPTIONS khỏi xác thực mọi lúc. Đã cập nhật – jlapoutre

+0

. cảm ơn @jlapoutre –

Các vấn đề liên quan