次の この質問 私は残りのコントローラーの動作を次のように設定しました
public function behaviors()
{
$behaviors = parent::behaviors();
$auth= $behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
'only' => ['dashboard'],
];
$behaviors['contentNegotiator'] = [
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
];
$acces=$behaviors['access'] = [
'class' => AccessControl::className(),
'only' => ['login'],
'rules' => [
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?'],
],
],
];
unset($behaviors['authenticator']);
unset($behaviors['access']);
そして今、CORSフィルター
// add CORS filter
$behaviors['corsFilter'] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to
'Access-Control-Allow-Origin' => ['*'],
'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
// 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' => 86400,
// Allow the X-Pagination-Current-Page header to be exposed to the browser.
'Access-Control-Expose-Headers' => [],
]
];
// re-add authentication filter
$behaviors['authenticator'] = $auth;
$behaviors['access'] = $access;
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
$behaviors['authenticator']['except'] = ['options'];
return $behaviors;
}
として私のangular2フロントエンド
const body = JSON.stringify(user);
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Content-Type', 'application/json');
headers.append('Access-Control-Allow-Credentials', "*");
return this._http.post(this.loginUrl, body, { headers:headers })
.map((response: Response) => {
//process response
})
.catch(this.handleError);
しかし、まだエラーが発生しています
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested resource. Origin
'http://localhost:3000' is therefore not allowed access.
Iveがyii2の動作でcorsフィルターを設定してオーセンティケーターの設定を解除し、後で追加したために間違っている可能性があるもの
CORSヘッダーに問題がある場合は、次の手順を使用することをお勧めします。
コントローラにcors設定を追加します。例えば:
/**
* List of allowed domains.
* Note: Restriction works only for AJAX (using CORS, is not secure).
*
* @return array List of domains, that can access to this API
*/
public static function allowedDomains() {
return [
// '*', // star allows all domains
'http://test1.example.com',
'http://test2.example.com',
];
}
/**
* @inheritdoc
*/
public function behaviors() {
return array_merge(parent::behaviors(), [
// For cross-domain AJAX request
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to domains:
'Origin' => static::allowedDomains(),
'Access-Control-Request-Method' => ['POST'],
'Access-Control-Allow-Credentials' => true,
'Access-Control-Max-Age' => 3600, // Cache (seconds)
],
],
]);
}
上記のコードは応答へ特別なhttp-headersを追加します。ブラウザデバッグツールを使用してhttp-headersを確認します。
Request http headerにはOrigin
を含める必要があります。クロスドメインAJAXでブラウザによって自動的に追加されます。このhttp-headerは、JSライブラリ経由でも追加できます。このhttp-headerがなければ、corsFilter
は機能しません。
POST /api/some-method-name HTTP/1.1
Host: api.example.com
Connection: keep-alive
Content-Length: 86
Accept: */*
Origin: https://my-site.example.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: https://my-site.example.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,ru;q=0.4
応答HTTPヘッダーにはAccess-Control-*
ヘッダー。このhttp-headerはcorsFilter
によって追加されます。
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://my-site.example.com
Content-Type: application/json; charset=UTF-8
Date: Fri, 24 Feb 2017 09:21:47 GMT
Server: Apache
Content-Length: 27
Connection: keep-alive
これらのhttpヘッダーが表示されない場合in responseの場合、おそらく\yii\filters\Cors
は機能しません。
コントローラの他の動作/フィルタを確認してください。 corsFilter
を最初の動作として追加してみてください。おそらく他のいくつかの動作がcorsFilter
の実行を妨げています。
このコントローラーに対してCSRF検証を無効にするを試してください(外部アクセスを妨げる可能性があります):
/**
* Controller for API methods.
*/
class ApiController extends Controller
{
/**
* @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}.
*/
public $enableCsrfValidation = false;
// ...
}
さらに、Webサーバーを確認する必要があります。おそらくnginxは追加の設定が必要かもしれませんが、Apacheはrestartingを必要とします。
Access-Control-*
応答のヘッダーは、Webサーバーを使用して追加できます( Apache および nginx を参照)。ただし、この場合はアプリケーションを使用してhttp-haderを管理できないため、この方法を使用することはお勧めしません。
いくつかの有用な情報はここで見つけることができます:
これを試して :
public static function allowedDomains()
{
return [
// '*', // star allows all domains
'http://localhost:3000',
'http://test2.example.com',
];
}
public function behaviors()
{
return array_merge(parent::behaviors(), [
// For cross-domain AJAX request
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to domains:
'Origin' => static::allowedDomains(),
'Access-Control-Request-Method' => ['POST'],
'Access-Control-Allow-Credentials' => true,
'Access-Control-Max-Age' => 3600, // Cache (seconds)
],
],
]);
}
この関数をコントローラーに追加します。
そして、One Thingangle2は初めてOPTIONメソッドを使用します
この問題は、フロントエンドがデフォルトのポート(80)以外のポートで実行されるときに発生します。
次に、yiiで動作するポートを指定する必要があります。例:フロントエンドはhttp: // localhost: 3000
in Yii cors set:
'Origin' => ['http: // localhost: 3000']
ポート(3000)を指定しない場合、Yiiはデフォルトでポートを解釈し、結果は次のようになります。
'Origin' => ['http: // localhost: 80']