Contrôle D'Accès-Autoriser-Origine Domaines D'Origine Multiples?

y a-t-il un moyen d'autoriser plusieurs domaines croisés en utilisant l'en-tête Access-Control-Allow-Origin ?

je suis au courant du * , mais il est trop ouvert. Je veux vraiment autoriser juste quelques domaines.

comme exemple, quelque chose comme ceci:

Access-Control-Allow-Origin: http://domain1.example, http://domain2.example

j'ai essayé le code ci-dessus, mais il ne semble pas fonctionner dans Firefox.

est-il possible de spécifier plusieurs domaines ou suis-je coincé avec un seul?

859
demandé sur Patrick Mevzek 2009-10-31 06:27:44

26 réponses

sonne comme la façon recommandée de le faire est d'avoir votre serveur lire l'en-tête D'Origine du client, comparez cela à la liste des domaines que vous souhaitez autoriser, et si elle correspond, faire écho à la valeur de l'en-tête Origin de retour au client comme l'en-tête Access-Control-Allow-Origin dans la réponse.

Avec .htaccess vous pouvez le faire comme ceci:

# ----------------------------------------------------------------------
# Allow loading of external fonts
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.example|dev02.otherdomain.example)$" AccessControlAllowOrigin="151900920"
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header merge Vary Origin
    </IfModule>
</FilesMatch>
741
répondu yesthatguy 2018-08-13 08:29:21

une autre solution que J'utilise en PHP:

$http_origin = $_SERVER['HTTP_ORIGIN'];

if ($http_origin == "http://www.domain1.com" || $http_origin == "http://www.domain2.com" || $http_origin == "http://www.domain3.com")
{  
    header("Access-Control-Allow-Origin: $http_origin");
}
170
répondu Nikolay Ivanov 2018-07-25 09:54:34

cela a fonctionné pour moi:

SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.example|domain2\.example)$" origin_is="151900920" 
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is

mis dans .htaccess , il fonctionnera à coup sûr.

98
répondu Jay Dave 2018-07-24 00:16:52

j'ai eu le même problème avec les polices woff, plusieurs sous-domaines devaient y avoir accès. Pour autoriser les sous-domaines, j'ai ajouté quelque chose comme ça à mon httpd.conf:

SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=
<FilesMatch "\.woff$">
    Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
</FilesMatch>

pour plusieurs domaines, vous pouvez simplement changer le regex dans SetEnvIf .

84
répondu Staugaard 2013-07-09 07:59:26

Voici comment faire écho à L'en-tête Origin si elle correspond à votre domaine avec Nginx, c'est utile si vous voulez servir une police de plusieurs sous-domaines:

location /fonts {
    # this will echo back the origin header
    if ($http_origin ~ "example.org$") {
        add_header "Access-Control-Allow-Origin" $http_origin;
    }
}
56
répondu mjallday 2012-09-13 20:25:22

voici ce que j'ai fait pour une application PHP qui est demandée par AJAX

$request_headers        = apache_request_headers();
$http_origin            = $request_headers['Origin'];
$allowed_http_origins   = array(
                            "http://myDumbDomain.example"   ,
                            "http://anotherDumbDomain.example"  ,
                            "http://localhost"  ,
                          );
if (in_array($http_origin, $allowed_http_origins)){  
    @header("Access-Control-Allow-Origin: " . $http_origin);
}

si l'origine de la requête est autorisée par mon serveur, retournez le $http_origin lui-même comme valeur de l'en-tête Access-Control-Allow-Origin au lieu de retourner un joker * .

22
répondu Syed Rakib Al Hasan 2018-07-24 00:17:36

il y a un inconvénient que vous devez savoir: dès que vous externalisez des fichiers vers un CDN (ou tout autre serveur qui ne permet pas le script) ou si vos fichiers sont mis en cache sur un proxy, modifier la réponse basée sur l'en-tête de requête "Origin" ne fonctionnera pas.

18
répondu Mark 2010-02-20 19:18:51

pour plusieurs domaines, dans votre .htaccess :

<IfModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(www\.)?(domain1.example|domain2.example)$" AccessControlAllowOrigin="151900920"
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header set Access-Control-Allow-Credentials true
</IfModule>
16
répondu George 2018-07-24 00:18:06

Pour IIS 7.5+ avec Réécriture d'URL 2.0 module installé, veuillez voir la section cette SORTE de réponse

14
répondu Paco Zarate 2017-05-23 12:34:54

pour les utilisateurs de Nginx pour autoriser les CORS pour plusieurs domaines. J'aime l'exemple de @marshall bien que ses vers ne correspondent qu'à un domaine. Pour faire correspondre une liste de domaine et de sous-domaine, ce regex rend facile de travailler avec les polices:

location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
   if ( $http_origin ~* (https?://(.+\.)?(domain1|domain2|domain3)\.(?:me|co|com)$) ) {
      add_header "Access-Control-Allow-Origin" "$http_origin";
   }
}

cela fera seulement écho aux en-têtes" Access-Control-Allow-Origin " qui correspondent à la liste de domaines donnée.

13
répondu Adriano Rosa 2015-01-10 18:31:14

Voici une solution pour Java Web app, basée sur la réponse de yesthatguy.

J'utilise Jersey REST 1.x

configurer le web.xml pour être au courant de Maillot de REPOS et de la CORSResponseFilter

 <!-- Jersey REST config -->
  <servlet>    
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param> 
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
      <param-value>com.your.package.CORSResponseFilter</param-value>
    </init-param>   
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.your.package</param-value>
    </init-param>        
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>

voici le code pour CORSResponseFilter

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;


public class CORSResponseFilter implements ContainerResponseFilter{

@Override
public ContainerResponse filter(ContainerRequest request,
        ContainerResponse response) {

    String[] allowDomain = {"http://localhost:9000","https://my.domain.example"};
    Set<String> allowedOrigins = new HashSet<String>(Arrays.asList (allowDomain));                  

    String originHeader = request.getHeaderValue("Origin");

    if(allowedOrigins.contains(originHeader)) {
        response.getHttpHeaders().add("Access-Control-Allow-Origin", originHeader);

        response.getHttpHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHttpHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }

    return response;
}

}
10
répondu duvo 2018-07-24 00:18:53

comme mentionné ci-dessus, Access-Control-Allow-Origin doit être unique et Vary doit être défini à Origin si vous êtes derrière un CDN (Content Delivery Network).

partie pertinente de ma configuration Nginx:

if ($http_origin ~* (https?://.*\.mydomain.example(:[0-9]+)?)) {
  set $cors "true";
}
if ($cors = "true") {
  add_header 'Access-Control-Allow-Origin' "$http_origin";
  add_header 'X-Frame-Options' "ALLOW FROM $http_origin";
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Vary' 'Origin';
}
7
répondu hernvnc 2018-08-31 06:59:05

peut-être que je me trompe, mais pour autant que je puisse voir Access-Control-Allow-Origin a un "origin-list" comme paramètre.

par définition an origin-list est:

origin            = "origin" ":" 1*WSP [ "null" / origin-list ]
origin-list       = serialized-origin *( 1*WSP serialized-origin )
serialized-origin = scheme "://" host [ ":" port ]
                  ; <scheme>, <host>, <port> productions from RFC3986

et de là, je soutiens que différentes origines sont admises et devraient être espace séparé .

6
répondu drAlberT 2018-07-24 00:20:11

j'ai eu du mal à le configurer pour un domaine fonctionnant sous HTTPS, donc j'ai pensé que je partagerais la solution. J'ai utilisé la directive suivante dans mon httpd.conf fichier:

    <FilesMatch "\.(ttf|otf|eot|woff)$">
            SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin="151900920"
            Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </FilesMatch>

modifier example.com pour votre nom de domaine. Ajoutez ceci dans <VirtualHost x.x.x.x:xx> dans votre httpd.fichier conf . Notez que si votre VirtualHost a un suffixe de port (par exemple :80 ) alors cette directive ne s'appliquera pas à HTTPS, donc vous devrez allez aussi à /etc/apache2/sites-available / default-ssl et ajoutez la même directive dans ce fichier, à l'intérieur de la section <VirtualHost _default_:443> .

une fois les fichiers de configuration mis à jour, vous devrez exécuter les commandes suivantes dans le terminal:

a2enmod headers
sudo service apache2 reload
5
répondu Alex W 2015-02-17 00:12:56

si vous avez des problèmes avec les polices, utilisez:

<FilesMatch "\.(ttf|ttc|otf|eot|woff)$">
    <IfModule mod_headers>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>
</FilesMatch>
4
répondu noun 2014-07-06 17:43:55

HTTP_ORIGIN n'est pas utilisé par tous les navigateurs. dans quelle mesure HTTP_ORIGIN est-il sécurisé? Pour moi il s'agit vide dans FF.

J'ai les sites que j'autorise l'accès à mon site Envoyer sur un ID de site, je vérifie ensuite ma DB pour l'enregistrement avec cet id et obtenir la valeur de la colonne SITE_URL (www.yoursite.com).

header('Access-Control-Allow-Origin: http://'.$row['SITE_URL']);

même si l'envoi d'un ID de site valide la demande doit provenir du domaine indiqué dans ma base de données associée à celui-ci site ID.

1
répondu mathius1 2017-05-23 12:34:54

Voici une option étendue pour apache qui inclut certaines des définitions de police les plus récentes et prévues:

<FilesMatch "\.(ttf|otf|eot|woff|woff2|sfnt|svg)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "^http(s)?://(.+\.)?(domainname1|domainname2|domainname3)\.(?:com|net|org)$" AccessControlAllowOrigin="151900920"
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header set Access-Control-Allow-Credentials true
    </IfModule>
</FilesMatch>
1
répondu Mike Kormendy 2015-10-15 22:31:33

et une autre réponse à Django. Pour avoir une vue unique autorise CORS de plusieurs domaines, voici mon code:

def my_view(request):
    if 'HTTP_ORIGIN' in request.META.keys() and request.META['HTTP_ORIGIN'] in ['http://allowed-unsecure-domain.com', 'https://allowed-secure-domain.com', ...]:
        response = my_view_response() # Create your desired response data: JsonResponse, HttpResponse...
        # Then add CORS headers for access from delivery
        response["Access-Control-Allow-Origin"] = request.META['HTTP_ORIGIN']
        response["Access-Control-Allow-Methods"] = "GET" # "GET, POST, PUT, DELETE, OPTIONS, HEAD"
        response["Access-Control-Max-Age"] = "1000"  
        response["Access-Control-Allow-Headers"] = "*"  
        return response
1
répondu Silvain 2016-09-28 11:05:28

pour faciliter l'accès à plusieurs domaines pour un service ASMX, j'ai créé cette fonction dans le global.fichier asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    string CORSServices = "/account.asmx|/account2.asmx";
    if (CORSServices.IndexOf(HttpContext.Current.Request.Url.AbsolutePath) > -1)
    {
        string allowedDomains = "http://xxx.yyy.example|http://aaa.bbb.example";

        if(allowedDomains.IndexOf(HttpContext.Current.Request.Headers["Origin"]) > -1)
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Headers["Origin"]);

        if(HttpContext.Current.Request.HttpMethod == "OPTIONS")
            HttpContext.Current.Response.End();
    }
}

cela permet aussi la manipulation du verbe OPTIONS par CORS.

1
répondu Derek Wade 2018-07-24 00:20:55

de Google de soutien de réponse sur la diffusion d'annonces sur SSL et le la grammaire dans la RFC lui-même semblerait indiquer que vous pouvez délimiter l'espace de l'Url. Pas sûr de savoir comment bien pris en charge c'est dans les différents navigateurs.

0
répondu Bob Aman 2013-10-18 12:46:03

si vous essayez tant d'exemples de code comme moi pour le faire fonctionner en utilisant CORS, il vaut la peine de mentionner que vous devez vider votre cache d'abord pour essayer si cela fonctionne réellement, similaire à des problèmes comme quand de vieilles images sont encore présentes, même si elle est supprimée sur le serveur (parce qu'elle est toujours sauvegardée dans votre cache).

par exemple CTRL + SHIFT + DEL dans Google Chrome pour supprimer votre cache.

cela m'a aidé à utiliser ce code après avoir essayé de nombreuses solutions pures .htaccess et cela semblait le seul travail (au moins pour moi):

    Header add Access-Control-Allow-Origin "http://google.com"
    Header add Access-Control-Allow-Headers "authorization, origin, user-token, x-requested-with, content-type"
    Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

    <FilesMatch "\.(ttf|otf|eot|woff)$">
        <IfModule mod_headers.c>
            SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.com|dev02.otherdomain.net)$" AccessControlAllowOrigin="151900920"
            Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        </IfModule>
    </FilesMatch>

notez également qu'il est largement répandu que de nombreuses solutions disent que vous devez taper Header set ... mais il est Header add ... . J'espère que ça aidera quelqu'un qui a les mêmes problèmes depuis des heures, comme moi.

0
répondu AlexioVay 2017-02-03 08:19:11

pour un copier / coller assez facile pour les applications .NET, j'ai écrit ceci pour activer CORS à l'intérieur d'un global.fichier asax. Ce code suit les conseils donnés dans la réponse actuellement acceptée, reflétant quelle que soit l'origine de retour est donnée dans la demande dans la réponse. Ce bien un '*' sans l'utiliser. La raison en est qu'il permet plusieurs autres fonctionnalités de CORS, y compris la possibilité d'envoyer un Ajax XMLHttpRequest avec l'attribut 'withCredentials' défini à 'true'.

void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.HttpMethod == "OPTIONS")
    {
        Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        Response.AddHeader("Access-Control-Max-Age", "1728000");
        Response.End();
    }
    else
    {
        Response.AddHeader("Access-Control-Allow-Credentials", "true");

        if (Request.Headers["Origin"] != null)
            Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]);
        else
            Response.AddHeader("Access-Control-Allow-Origin" , "*");
    }
}
0
répondu QA Collective 2017-12-21 01:24:31

une approche plus souple consiste à utiliser les expressions D'Apache 2.4. Vous pouvez faire la correspondance avec les domaines, les chemins, et à peu près toutes les autres variables de requête. Bien que la réponse soit * pour tous, les seuls demandeurs qui reçoivent cette réponse sont ceux qui satisfont de toute façon aux exigences.

<IfModule mod_headers.c>
    <If "%{HTTP:Host} =~ /\byourdomain\.example$/i">
        Header set Access-Control-Allow-Origin "*"
    </If>
</IfModule>
0
répondu Walf 2018-07-24 00:21:38

exemple de code PHP pour les sous-domaines correspondants.

if( preg_match("/http:\/\/(.*?)\.yourdomain.example/", $_SERVER['HTTP_ORIGIN'], $matches )) {
        $theMatch = $matches[0];
        header('Access-Control-Allow-Origin: ' . $theMatch);
}
0
répondu blak3r 2018-07-24 00:22:00

, La réponse semble être d'utiliser l'en-tête plus d'une fois. Autrement dit, plutôt que d'envoyer

Access-Control-Allow-Origin: http://domain1.example, http://domain2.example, http://domain3.example

envoyer

Access-Control-Allow-Origin: http://domain1.example
Access-Control-Allow-Origin: http://domain2.example
Access-Control-Allow-Origin: http://domain3.example

sur Apache, vous pouvez le faire dans une section httpd.conf <VirtualHost> ou .htaccess en utilisant mod_headers et cette syntaxe:

Header add Access-Control-Allow-Origin "http://domain1.example"
Header add Access-Control-Allow-Origin "http://domain2.example"
Header add Access-Control-Allow-Origin "http://domain3.example"

L'astuce est d'utiliser add plutôt que append comme premier argument.

-1
répondu Ben C. Forsberg 2018-07-24 00:22:44

on peut aussi mettre ça dans Global.fichier asax pour Asp.net application.

protected void Application_BeginRequest(object sender, EventArgs e)
    {

    // enable CORS
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "https://www.youtube.com");

    }
-2
répondu sudhAnsu63 2015-03-31 11:59:45