Acesso-Controlo-Permitir-Origem Domínios De Origem Múltipla?

Existe uma forma de permitir vários domínios cruzados usando o cabeçalho Access-Control-Allow-Origin?

Estou ciente do *, mas está demasiado aberto. Eu realmente quero permitir apenas alguns domínios.

como exemplo, algo assim:

Access-Control-Allow-Origin: http://domain1.example, http://domain2.example
Tentei o código acima, mas não parece funcionar no Firefox.

é possível especificar vários domínios ou estou preso com apenas um?

Author: Patrick Mevzek, 2009-10-31

26 answers

Soa como a forma recomendada de o fazer é fazer com que o seu servidor leia o cabeçalho de origem do cliente, compare-o com a lista de domínios que gostaria de permitir e, se corresponder, faça eco do valor do cabeçalho Origin de volta para o cliente como o cabeçalho Access-Control-Allow-Origin na resposta.

Com .htaccess podes fazê - lo assim:

# ----------------------------------------------------------------------
# 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=$0
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header merge Vary Origin
    </IfModule>
</FilesMatch>
 741
Author: yesthatguy, 2018-08-13 08:29:21

Outra solução que estou a usar em 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
Author: Nikolay Ivanov, 2018-07-25 09:54:34
Isto funcionou comigo.
SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.example|domain2\.example)$" origin_is=$0 
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is

Quando colocado em .htaccess, vai funcionar de certeza.

 98
Author: Jay Dave, 2018-07-24 00:16:52
Tive o mesmo problema com o WOFF-fonts, vários subdomínios tinham de ter acesso. Para permitir subdomínios, adicionei algo assim à minha httpd.conf:
SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=$1
<FilesMatch "\.woff$">
    Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
</FilesMatch>

Para vários domínios, pode alterar a expressão regular em SetEnvIf.

 84
Author: Staugaard, 2013-07-09 07:59:26

Aqui está como fazer eco ao cabeçalho de origem se corresponder ao seu domínio com o Nginx, isto é útil se quiser servir um tipo de letra vários sub-domínios:

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

Aqui está o que eu fiz para uma aplicação PHP que está a ser solicitada pelo 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);
}

Se a origem do pedido for permitida pelo meu servidor, devolve o $http_origin em si como valor do cabeçalho Access-Control-Allow-Origin em vez de devolver uma sequência especial *.

 22
Author: Syed Rakib Al Hasan, 2018-07-24 00:17:36

Há uma desvantagem que você deve estar ciente: assim que você sair arquivos de código para um CDN (ou qualquer outro servidor que não permite scripting) ou se seus arquivos são cache em um proxy, alterando a resposta com base no cabeçalho de pedido de 'origem' não vai funcionar.

 18
Author: Mark, 2010-02-20 19:18:51

Para vários domínios, no seu .htaccess:

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

Para o IIS 7. 5+ com o módulo de reescrita do URL 2. 0 instalado veja por favor isto assim responde

 14
Author: Paco Zarate, 2017-05-23 12:34:54

Para os utilizadores do Nginx, permitir o CORS para vários domínios. Gosto do exemplo de @marshall, embora os seus anwers só correspondam a um domínio. Para corresponder a uma lista de domínio e subdomínios, este regex torna mais fácil trabalhar com tipos de letra:

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";
   }
}

Isto só fará eco dos cabeçalhos" Access-Control-Allow-Origin" que correspondem à lista de domínios indicada.

 13
Author: Adriano Rosa, 2015-01-10 18:31:14

Aqui está uma solução para o aplicativo Web Java, baseado na resposta de yesthatguy.

Estou a usar Jersey REST 1.x

Configure a web.xml estar ciente do repouso de Jersey e do 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>
Aqui está o código para 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
Author: duvo, 2018-07-24 00:18:53

Como mencionado acima, Access-Control-Allow-Origin deve ser único e {[2] } deve ser definido para Origin Se estiver por detrás de uma rede de distribuição de conteúdo.

Parte relevante da minha configuração de 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
Author: hernvnc, 2018-08-31 06:59:05

Talvez eu esteja errado, mas tanto quanto posso ver Access-Control-Allow-Origin tem um "origin-list" como parâmetro.

Por definição o origin-list é:

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

E a partir disto, eu defendo que origens diferentes são admitidas e devem serseparadas por espaço .

 6
Author: drAlberT, 2018-07-24 00:20:11
Esforcei-me para criar isto para um domínio a correr HTTPS, por isso pensei em partilhar a solução. Usei a seguinte directiva no meu httpd.conf ficheiro:
    <FilesMatch "\.(ttf|otf|eot|woff)$">
            SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin=$0
            Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </FilesMatch>

Mudar {[2] } para o seu nome de domínio. Adicione isto dentro do <VirtualHost x.x.x.x:xx> no seu httpd.conf ficheiro. Repare que, se o seu VirtualHost tiver um sufixo de porto (por exemplo :80), a presente directiva não se aplica aos HTTPS, pelo que terá de ir também a / etc / apache2/sites-available / default-ssl e adicionar a mesma directiva nesse ficheiro, dentro da Secção <VirtualHost _default_:443>.

Assim que os ficheiros de configuração forem actualizados, terá de executar os seguintes comandos no terminal:

a2enmod headers
sudo service apache2 reload
 5
Author: Alex W, 2015-02-17 00:12:56

Se TEM problemAs com tipos de letra, use:

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

O HTTP_ origin não é utilizado por todos os navegadores. Quão seguro é o HTTP_ origin?Para mim, não tem nada em FF.
Eu tenho os sites que eu permitir o acesso ao meu site enviar um ID do site, Eu então verificar o meu DB para o registro com esse id e obter o valor da coluna SITE_URL (www.yoursite.com).

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

Mesmo que o envio de um ID de site válido o pedido precisa ser do domínio listado no meu DB associado a esse ID de site.

 1
Author: mathius1, 2017-05-23 12:34:54

Aqui está uma opção expandida para o apache que inclui algumas das mais recentes e planejadas definições de tipos de letra:

<FilesMatch "\.(ttf|otf|eot|woff|woff2|sfnt|svg)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "^http(s)?://(.+\.)?(domainname1|domainname2|domainname3)\.(?:com|net|org)$" AccessControlAllowOrigin=$0$1$2
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header set Access-Control-Allow-Credentials true
    </IfModule>
</FilesMatch>
 1
Author: Mike Kormendy, 2015-10-15 22:31:33
E mais uma resposta em Django. Para ter uma única vista permitir o CORS de vários domínios, aqui está o meu código:
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
Author: Silvain, 2016-09-28 11:05:28

Para facilitar o acesso a vários domínios para um serviço ASMX, criei esta função no global.ficheiro 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();
    }
}

Isto também permite a manipulação de CORS de OPTIONS verbo.

 1
Author: Derek Wade, 2018-07-24 00:20:55

A resposta de suporte do Google em a servir anúncios sobre SSL e a gramática na própria RFC parece indicar que pode delimitar os URLs no espaço. Não sei se isto é bem suportado em diferentes navegadores.

 0
Author: Bob Aman, 2013-10-18 12:46:03

Se você tentar tantos exemplos de código, como eu, para fazer o trabalho usando o CORS, vale a pena mencionar que você tem que limpar seu cache pela primeira vez para tentar se ele realmente funciona, similar a questões como quando imagens antigas ainda estão presentes, mesmo se não eliminados no servidor (porque ele ainda está guardado na cache).

Por exemplo CTRL + SHIFT + DEL no Google Chrome para apagar a sua 'cache'.

Isto ajudou-me a usar este código depois de tentar muitas soluções puras e isto. parecia o único a trabalhar (pelo menos para mim):
    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=$0
            Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        </IfModule>
    </FilesMatch>

Note também que é amplamente difundido que muitas soluções dizem que você tem que digitar Header set ... mas é Header add .... Espero que isto ajude alguém a ter os mesmos problemas há algumas horas como eu.

 0
Author: AlexioVay, 2017-02-03 08:19:11

Para uma cópia / pasta bastante fácil para aplicações.net, escrevi isto para activar o CORS a partir de um global.ficheiro asax. Este código segue os conselhos dados na resposta atualmente aceita, refletindo qualquer origem que seja dada no pedido na resposta. Isto consegue efectivamente " * " sem o utilizar. A razão para isso é que ele permite vários outros recursos do CORS, incluindo a capacidade de enviar um AJAX XMLHttpRequest com o atributo "witcredentials" definido para "verdade".

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
Author: QA Collective, 2017-12-21 01:24:31

Uma abordagem mais flexível é usar as expressões do Apache 2.4. Você pode comparar com domínios, caminhos e quase todas as outras variáveis de pedido. Embora a resposta seja * para todos, os únicos que recebem essa resposta são aqueles que cumprem os requisitos de qualquer maneira.

<IfModule mod_headers.c>
    <If "%{HTTP:Host} =~ /\\byourdomain\\.example$/i">
        Header set Access-Control-Allow-Origin "*"
    </If>
</IfModule>
 0
Author: Walf, 2018-07-24 00:21:38
Exemplo de código PHP para subdomínios correspondentes.
if( preg_match("/http:\/\/(.*?)\.yourdomain.example/", $_SERVER['HTTP_ORIGIN'], $matches )) {
        $theMatch = $matches[0];
        header('Access-Control-Allow-Origin: ' . $theMatch);
}
 0
Author: blak3r, 2018-07-24 00:22:00

A resposta parece ser usar o cabeçalho mais de uma vez. Isto é, em vez de enviar {[11]

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

Enviar

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

Em Apache, você pode fazer isso em um httpd.conf <VirtualHost> secção ou .htaccess ficheiro usando mod_headers e esta sintaxe:

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"

O truque é usar add em vez de append como primeiro argumento.

 -1
Author: Ben C. Forsberg, 2018-07-24 00:22:44
[[2] nós também podemos definir isso em Global.ficheiro asax para Asp.net aplicação.
protected void Application_BeginRequest(object sender, EventArgs e)
    {

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

    }
 -2
Author: sudhAnsu63, 2015-03-31 11:59:45