Sous-domaines, ports et protocoles joker, access-control-allow-origin

J’essaie d’activer CORS pour tous les sous-domaines, ports et protocoles.

Par exemple, je veux pouvoir exécuter une demande XHR depuis http://sub.mywebsite.com:8080/ vers https://www.mywebsite.com/ *

En règle générale, je voudrais activer la demande des origines correspondant (et limitée à):

//*.mywebsite.com:*/*

Sur la base de la réponse de DaveRandom, je jouais également et trouvais une solution Apache légèrement plus simple qui produit le même résultat ( Access-Control-Allow-Origin est défini sur le protocole spécifique actuel + domaine + port de manière dynamic) sans utiliser de règles de réécriture:

 SetEnvIf Origin ^(https?://.+\.mywebsite\.com(?::\d{1,5})?)$ CORS_ALLOW_ORIGIN=$1 Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN Header merge Vary "Origin" 

Et c’est tout.

Ceux qui veulent activer CORS sur le domaine parent (par exemple, mywebsite.com) en plus de tous ses sous-domaines peuvent simplement remplacer l’expression régulière dans la première ligne par celle-ci:

^(https?://(?:.+\.)?mywebsite\.com(?::\d{1,5})?)$ .

Remarque: Pour la conformité aux spécifications et le comportement correct de la mise en cache, ajoutez TOUJOURS l’en-tête de réponse Vary: Origin pour les ressources compatibles CORS, même pour les requêtes non-CORS et celles d’origine non autorisée (voir exemple ).

La spécification CORS est tout ou rien. Il ne supporte que * , null ou le protocole + domaine + port exact: http://www.w3.org/TR/cors/#access-control-allow-origin-response-header

Votre serveur devra valider l’en-tête d’origine à l’aide de l’expression rationnelle, puis vous pourrez faire écho à la valeur d’origine dans l’en-tête de réponse Access-Control-Allow-Origin.

EDIT : Utilisez la solution de @ Noyo au lieu de celle-ci. C’est plus simple, plus clair et probablement beaucoup plus performant sous charge.

RÉPONSE ORIGINALE À GAUCHE ICI À DES FINS HISTORIQUES SEULEMENT !!


J’ai fait quelques essais avec ce problème et j’ai mis au point cette solution réutilisable .htaccess (ou httpd.conf) compatible avec Apache:

   # Define the root domain that is allowed SetEnvIf Origin .+ ACCESS_CONTROL_ROOT=yourdomain.com # Check that the Origin: matches the defined root domain and capture it in # an environment var if it does RewriteEngine On RewriteCond %{ENV:ACCESS_CONTROL_ROOT} !="" RewriteCond %{ENV:ACCESS_CONTROL_ORIGIN} ="" RewriteCond %{ENV:ACCESS_CONTROL_ROOT}&%{HTTP:Origin} ^([^&]+)&(https?://(?:.+?\.)?\1(?::\d{1,5})?)$ RewriteRule .* - [E=ACCESS_CONTROL_ORIGIN:%2] # Set the response header to the captured value if there was a match Header set Access-Control-Allow-Origin %{ACCESS_CONTROL_ORIGIN}e env=ACCESS_CONTROL_ORIGIN   

Il suffit de définir la variable ACCESS_CONTROL_ROOT en haut du bloc sur votre domaine racine et elle fera écho à la valeur d’en-tête de demande Origin: au client dans la valeur de l’en Access-Control-Allow-Origin: tête de réponse Access-Control-Allow-Origin:

Notez également que vous pouvez utiliser sub.mydomain.com comme ACCESS_CONTROL_ROOT et limiter les origines à sub.mydomain.com et *.sub.mydomain.com (c.-à- sub.mydomain.com *.sub.mydomain.com ne doit pas nécessairement être la racine du domaine). Les éléments autorisés à varier (protocole, port) peuvent être contrôlés en modifiant la partie correspondant à l’URI du regex.

Je réponds à cette question, car la réponse acceptée ne peut pas correspondre au domaine primaire et ne fonctionne que pour le sous-domaine. De plus, le regroupement d’expressions rationnelles est un problème de performance , ce qui n’est pas nécessaire.

Par exemple: il n’enverra pas les en-têtes CORS pour http://mywebsite.com alors que fonctionne pour http://somedomain.mywebsite.com/

 SetEnvIf Origin "http(s)?://(.+\.)?mywebsite\.com(:\d{1,5})?$" CORS=$0 Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS Header merge Vary "Origin" 

Pour activer votre site, il vous suffit de placer votre site à la place de “mywebsite.com” dans la configuration Apache ci-dessus.

Autoriser plusieurs sites:

 SetEnvIf Origin "http(s)?://(.+\.)?(othersite\.com|mywebsite\.com)(:\d{1,5})?$" CORS=$0 

Tester après le déploiement:

La réponse en boucle suivante doit avoir l’en-tête “Access-Control-Allow-Origin” après la modification.

 curl -X GET -H "Origin: http://examplesite1.com" --verbose http://examplesite2.com/query 

J’avais besoin d’une solution PHP uniquement, donc juste au cas où quelqu’un en aurait également besoin. Il prend une chaîne de saisie autorisée telle que “* .exemple.com” et renvoie le nom du serveur d’en-tête de requête, si l’entrée correspond.

 function getCORSHeaderOrigin($allowed, $input) { if ($allowed == '*') { return '*'; } $allowed = preg_quote($allowed, '/'); if (($wildcardPos = strpos($allowed, '*')) !== false) { $allowed = str_replace('*', '(.*)', $allowed); } $regexp = '/^' . $allowed . '$/'; if (!preg_match($regexp, $input, $matches)) { return 'none'; } return $input; } 

Et voici les cas de test pour un fournisseur de données phpunit:

 //     array('Allow Subdomain', 'www.example.com', 'www.example.com', 'www.example.com'), array('Disallow wrong Subdomain', 'www.example.com', 'ws.example.com', 'none'), array('Allow All', '*', 'ws.example.com', '*'), array('Allow Subdomain Wildcard', '*.example.com', 'ws.example.com', 'ws.example.com'), array('Disallow Wrong Subdomain no Wildcard', '*.example.com', 'example.com', 'none'), array('Allow Double Subdomain for Wildcard', '*.example.com', 'abexample.com', 'abexample.com'), array('Don\'t fall for incorrect position', '*.example.com', 'a.example.com.evil.com', 'none'), array('Allow Subdomain in the middle', 'a.*.example.com', 'a.bc.example.com', 'a.bc.example.com'), array('Disallow wrong Subdomain', 'a.*.example.com', 'b.bc.example.com', 'none'), array('Correctly handle dots in allowed', 'example.com', 'exampleXcom', 'none'), 

Nous avions des problèmes similaires avec Font Awesome sur un domaine statique “sans cookies” lors de la lecture des fonts du “domaine des cookies” (www.domain.tld) ​​et cet article était notre héros. Voir ici: Comment puis-je résoudre le problème WebFont de l’en-tête de réponse «CORS (Missing Cross-Origin Resource Sharing)»?

Pour les types copy / paste-r (et pour donner quelques accessoires), j’ai rassemblé toutes les consortingbutions et je les ai ajoutées au début du fichier .htaccess de la racine du site:

SetEnvIf Origin "http(s)?://(.+\.)?(othersite\.com|mywebsite\.com)(:\d{1,5})?$" CORS=$0 Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS Header merge Vary "Origin"

Super sécurisé, super élégant. Love it: Vous n’avez pas à ouvrir la bande passante de vos serveurs pour les types de voleurs / hot-link-er.

Les accessoires à: @Noyo @DaveRandom @ pratap-koritala

(J’ai essayé de laisser cela comme un commentaire à la réponse acceptée, mais je ne peux pas encore le faire)

Il semble que la réponse originale était pour la version antérieure à Apache 2.4. Cela n’a pas fonctionné pour moi. Voici ce que j’ai dû changer pour le faire fonctionner en 2.4. Cela fonctionnera pour toute profondeur de sous-domaine de yourcompany.com .

 SetEnvIf Host ^((?:.+\.)*yourcompany\.com?)$ CORS_ALLOW_ORIGIN=$1 Header append Access-Control-Allow-Origin %{REQUEST_SCHEME}e://%{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN Header merge Vary "Origin" 

Avec un léger changement sur la réponse de Lars.