Issue
Following This question i have set my rest controller behaviour as
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']);
And now the cors filters
// 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;
}
An my angular2 frontend as
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);
But am still getting an error of
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.
What could be wrong since ive set the cors filter in yii2 behaviours unset authenticator and added it later What could i be missing out
I have also checked on This link and also this one but none solves the issue
Solution
In case of any problems with CORS headers, I recommend to use following instruction:
Add cors configuration to your controller. For instance:
/** * 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) ], ], ]); }
The above code will add to response special http-headers. Check http-headers using browser debug tools:
Request http header should contain
Origin
. It will be added by browser automatically at Crossdomain AJAX. This http-header can be added also via your JS library. Without this http-headercorsFilter
won't work.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
Response http headers should contain
Access-Control-*
headers. This http-header will be added bycorsFilter
.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
If you don't see these http headers in response, probably it means that
\yii\filters\Cors
doesn't work or conflicts with other filters.Check other behaviors/filters in controller. Try add
corsFilter
as first behavior. Probably some other behaviors prevents execution ofcorsFilter
.Try to disable CSRF validation for this controller (it may prevent external access):
/** * Controller for API methods. */ class ApiController extends Controller { /** * @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}. */ public $enableCsrfValidation = false; // ... }
If you are using authenticator filter (for example, your controller extends
yii\rest\ActiveController
) the CORS filter has to be applied BEFORE authentication methods. Also authentication has to be disabled for the CORS Preflight requests so that a browser can safely determine whether a request can be made beforehand without the need for sending authentication credentials.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; }
Additionally should be checked your web-server. Probably nginx may require additional configuration, apache can require restarting.
Access-Control-*
headers in response can be added using web-server (see for apache and nginx). But I don't recommend to use this way, because in this case you can't manage http-haders using application.Some useful information can be found here:
Answered By - IStranger
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.