Commit 6dc056b3 by Philippe Gaultier Committed by Alexander Makarov

#4388: CORS filter fixes:

- Upgrade the documentation to match filter code - Fix bad default behavior with Access-Control-Allow-Credentials - Fix missing "s" in header Access-Control-Request-Method / Access-Control-Allow-Methods
parent e486b663
......@@ -346,10 +346,10 @@ The Cors filtering could be tuned using the `cors` property.
* `cors['Origin']`: array used to define allowed origins. Can be `['*']` (everyone) or `['http://www.myserver.net', 'http://www.myotherserver.com']`. Default to `['*']`.
* `cors['Access-Control-Request-Method']`: array of allowed verbs like `['GET', 'OPTIONS', 'HEAD']`. Default to `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']`.
* `cors['Access-Control-Request-Headers']`: array of allowed headers. Can be `['*']` all headers or specific ones `['X-Request-With']`. Default to `['*']`.
* `cors['Access-Control-Allow-Credentials']`: define if current request can be made using credentials. Can be `true`, `false`. Default to `true`.
* `cors['Access-Control-Allow-Credentials']`: define if current request can be made using credentials. Can be `true`, `false` or `null` (not set). Default to `null`.
* `cors['Access-Control-Max-Age']`: define lifetime of pre-flight request. Default to `86400`.
For example, allowing CORS for origin : `http://www.myserver.net` with method `GET`, `HEAD` and `OPTIONS` and do not send `Access-Control-Allow-Credentials` header :
For example, allowing CORS for origin : `http://www.myserver.net` with method `GET`, `HEAD` and `OPTIONS` :
```php
use yii\filters\Cors;
......@@ -363,7 +363,6 @@ public function behaviors()
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
'Access-Control-Allow-Credentials' => null,
],
],
], parent::behaviors());
......@@ -385,7 +384,6 @@ public function behaviors()
'cors' => [
'Origin' => ['http://www.myserver.net'],
'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
'Access-Control-Allow-Credentials' => null,
],
'actions' => [
'login' => [
......
......@@ -79,7 +79,7 @@ class Cors extends ActionFilter
'Origin' => ['*'],
'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
'Access-Control-Request-Headers' => ['*'],
'Access-Control-Allow-Credentials' => true,
'Access-Control-Allow-Credentials' => null,
'Access-Control-Max-Age' => 86400,
];
......@@ -151,14 +151,19 @@ class Cors extends ActionFilter
}
}
$this->prepareAllowHeaders('Method', $requestHeaders, $responseHeaders);
$this->prepareAllowHeaders('Headers', $requestHeaders, $responseHeaders);
if (isset($requestHeaders['Access-Control-Request-Method'])) {
$responseHeaders['Access-Control-Allow-Methods'] = implode(', ', $this->cors['Access-Control-Request-Method']);
}
if ($this->cors['Access-Control-Allow-Credentials'] === true) {
$responseHeaders['Access-Control-Allow-Credentials'] = 'true';
} elseif ($this->cors['Access-Control-Allow-Credentials'] === false) {
$responseHeaders['Access-Control-Allow-Credentials'] = 'false';
}
if (($_SERVER['REQUEST_METHOD'] === 'OPTIONS') && ($this->cors['Access-Control-Max-Age'] !== null)) {
$responseHeaders['Access-Control-Max-Age'] = $this->cors['Access-Control-Max-Age'];
}
......@@ -178,20 +183,12 @@ class Cors extends ActionFilter
$responseHeaderField = 'Access-Control-Allow-'.$type;
if (isset($requestHeaders[$requestHeaderField])) {
if (in_array('*', $this->cors[$requestHeaderField])) {
if ($type === 'Method') {
$responseHeaders[$responseHeaderField] = strtoupper($requestHeaders[$requestHeaderField]);
} elseif ($type === 'Headers') {
$responseHeaders[$responseHeaderField] = $this->headerize($requestHeaders[$requestHeaderField]);
}
$responseHeaders[$responseHeaderField] = $this->headerize($requestHeaders[$requestHeaderField]);
} else {
$requestedData = preg_split("/[\s,]+/", $requestHeaders[$requestHeaderField], -1, PREG_SPLIT_NO_EMPTY);
$acceptedData = [];
foreach ($requestedData as $req) {
if ($type === 'Method') {
$req = strtoupper($req);
} elseif ($type === 'Headers') {
$req = $this->headerize($req);
}
$req = $this->headerize($req);
if (in_array($req, $this->cors[$requestHeaderField])) {
$acceptedData[] = $req;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment