Cette question j'ai défini le comportement de mon contrôleur de repos comme
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']);
Et maintenant les filtres 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;
}
Un front my angular2 comme
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);
Mais je reçois toujours une erreur de
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.
Quel pourrait être le problème depuis que j'ai mis le filtre cors dans les comportements yii2, désactivez l'authentificateur et l'ajouté plus tard Que puis-je manquer
J'ai également vérifié Ce lien et aussi celui-ci mais aucun ne résout le problème
En cas de problème avec les en-têtes CORS, je recommande d'utiliser les instructions suivantes:
Ajoutez la configuration de cors à votre contrôleur. Par exemple:
/**
* 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)
],
],
]);
}
Le code ci-dessus ajoutera à la réponse en-têtes http spéciaux. Vérifiez les en-têtes http à l'aide des outils de débogage du navigateur:
L'en-tête http de la demande doit contenir Origin
. Il sera ajouté automatiquement par le navigateur sur Crossdomain AJAX. Cet en-tête http peut également être ajouté via votre bibliothèque JS. Sans cet en-tête http corsFilter
ne fonctionnera pas.
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
Les en-têtes http de réponse doivent contenir Access-Control-*
en-têtes. Cet en-tête http sera ajouté par 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
Si vous ne voyez pas ces en-têtes http en réponse , cela signifie probablement que \yii\filters\Cors
ne fonctionne pas.
Vérifiez les autres comportements/filtres dans le contrôleur. Essayez d'ajouter corsFilter
comme premier comportement . Certains autres comportements empêchent probablement l'exécution de corsFilter
.
Essayez de désactiver la validation CSRF pour ce contrôleur (cela peut empêcher l'accès externe):
/**
* Controller for API methods.
*/
class ApiController extends Controller
{
/**
* @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}.
*/
public $enableCsrfValidation = false;
// ...
}
En outre, vous devez vérifier votre serveur Web. Nginx peut probablement nécessiter une configuration supplémentaire, Apache peut nécessiter un redémarrage .
Access-Control-*
les en-têtes en réponse peuvent être ajoutés en utilisant un serveur web (voir pour Apache et nginx ). Mais je ne recommande pas d'utiliser cette méthode, car dans ce cas, vous ne pouvez pas gérer les utilisateurs http à l'aide d'une application.
Quelques informations utiles peuvent être trouvées ici:
Essaye ça :
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)
],
],
]);
}
Ajoutez cette fonction sur votre contrôleur.
Et One Thing angular2 utilise la méthode OPTION pour la première fois.
Le problème survient lorsque le frontend s'exécute dans un port autre que le port par défaut (80).
Ensuite, dans yii vous devez spécifier le port à travailler. Exemple: le frontend s'exécute à http: // localhost: 3000
in Yii cors set:
'Origin' => ['http: // localhost: 3000']
Si vous ne spécifiez pas le port (3000), Yii interprète le port par défaut et le résultat est:
'Origin' => ['http: // localhost: 80']