Access-Control-Allow-Origin Domini di origine multipli?


1049

Esiste un modo per consentire più domini diversi usando l' Access-Control-Allow-Originintestazione?

Ne sono consapevole *, ma è troppo aperto. Voglio davvero consentire solo un paio di domini.

Ad esempio, qualcosa del genere:

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

Ho provato il codice sopra ma non sembra funzionare in Firefox.

È possibile specificare più domini o sono bloccato con uno solo?



3
Utilizzando il più recente Firefox, né i domini separati da virgola né quelli separati da spazi funzionavano. La corrispondenza con un elenco di domini e l'inserimento di un singolo host nelle intestazioni è ancora maggiore sicurezza e funziona correttamente.
Daniel W.

1
Se stai lottando con questo per HTTPS, ho trovato una soluzione .
Alex W,

7
nota importante : consentire solo i domini cretainAccess-Control-Allow-Originnell'intestazione non significa che altri domini non possano attivare un metodo su questo endpoint (es. metodo API REST). Significa solo che le origini non consentite non possono utilizzare il risultato in JavaScript (il browser lo assicura). Per limitare l'accesso a un endpoint per domini specifici, utilizzare un filtro di richiesta sul lato server che, ad esempio, restituisce HTTP 401 per domini non consentiti.
Klues

1
Dovresti sempre aggiungere l' Vary: Originintestazione quando vuoi usare più URL, vedi: fetch.spec.whatwg.org/#cors-protocol-and-http-caches
Null

Risposte:


861

Sembra che il modo consigliato per farlo sia fare in modo che il tuo server legga l'intestazione Origin dal client, confrontalo con l'elenco dei domini che desideri consentire e, se corrisponde, fai eco al valore Origindell'intestazione sul client come l' Access-Control-Allow-Originintestazione nella risposta.

Con .htaccesste puoi farlo in questo modo:

# ----------------------------------------------------------------------
# Allow loading of external fonts
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
    <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>

41
Questo corrisponde a ciò che suggerisce il W3C - w3.org/TR/cors/#access-control-allow-origin-response-hea
Simon B.

153
Il mio problema con questa risposta è che non mi aiuta davvero, perché usiamo una CDN e ovviamente non possiamo controllare come la CDN imposta le intestazioni a livello di codice.
BT,

6
Esempio reale (Nginx) nella mia risposta qui sotto - stackoverflow.com/a/12414239/6084
mjallday

71
Se le cache o le CDN rappresentano un problema, utilizzare l' intestazione Vary per indicare alla cache / CDN di mantenere risposte separate per valori di intestazione della richiesta Origin diversi. Includeresti un'intestazione come "Vary: Origin" nella tua risposta. La cache / CDN quindi sa che dovrebbe inviare una risposta a una richiesta con intestazione "Origin: foo.example.com " e una risposta diversa a una richiesta con intestazione "Origin: bar.example.com ".
Sean,

10
@saturdayplace, se hai accesso all'intestazione Origin, hai superato CORS.
Paul Draper,

222

Un'altra soluzione che sto usando in 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");
}

12
Perché non utilizzare l'approccio suggerito in stackoverflow.com/a/1850482/11635 [e non ha inviato un carattere jolly, solo l'origine richiesta]? Questo è solo più permissivo senza ottenere nulla di più?
Ruben Bartelink,

15
avendo a header('Access-Control-Allow-Origin: *')volte dice che non è possibile utilizzare il carattere jolly se la bandiera delle credenziali è vera - succede quando header('Access-Control-Allow-Credentials: true')probabilmente. Quindi, meglio consentire a Origin di per $http_originsé se le condizioni sono soddisfatte
Rakib,

6
sostituisci l'ultima riga con header("Access-Control-Allow-Origin: " . $http_origin);per farla funzionare
François Romain

2
Questo codice appare imperfetto, in quanto se non viene riconosciuta alcuna intestazione HTTP_ORIGIN, nessun Access-Control-Allow-Origin è impostato, lasciando lo script completamente aperto.
Stephen R,

9
@StephenR in realtà "completamente chiuso" sarebbe più accurato, poiché lo scopo di questo è quello di aprire lo script ad altri domini;)
Kaddath

113

Questo ha funzionato per me:

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

Una volta inserito .htaccess, funzionerà sicuramente.


24
la migliore soluzione per me, ma ho aggiunto il supporto delle porte (ad es. localhost: 3000 per lo sviluppo): SetEnvIf Origin "^ http (s)?: // (. + \.)? (localhost | stackoverflow.com | example1.com) ( : [0-9] +)? $ "Origin_is = $ 0
vszurma

2
Delle diverse risposte su stackoverflow, questa è stata quella che ha funzionato.
Meetai.com,

Ho dovuto aggiungere Header set Access-Control-Allow-Credentials trueper farlo funzionare come la risposta di @George
99 Problemi - La sintassi non è una

Questo funziona sicuramente quando uso Origin. Ma in alcuni casi, Origin non è disponibile in alcune richieste ed è anche specifico del browser. Quindi, ho deciso di utilizzare Refererinvece di Origin. Usando Refererfunziona ma il problema è che reimposta l'URL completo su Access-Control-Allow-Origincui voglio tagliare il nome di dominio Referere assegnarlo a Access-Control-Allow-Origin. Qualcosa come il risultato di questo - echo http://example.com/index.php/ab/cd | cut -d'/' -f1,2,3nel comando bash. È possibile fare lo stesso nel file conf (apache)? Qualche idea?
3AK,

1
Questo non funziona per me. Errore sempre nel codice 500 quando aggiungo le 2 righe. In realtà usando PHP 5.6.15
BoCyrill

91

Ho avuto lo stesso problema con i caratteri woff, a più sottodomini doveva essere consentito l'accesso. Per consentire i sottodomini ho aggiunto qualcosa di simile al mio 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>

Per più domini potresti semplicemente cambiare la regex in SetEnvIf.


4
Ha fatto il trucco. Assicurati di adattare correttamente l'espressione regolare. Avevo bisogno di aggiungere un punto interrogativo per consentire il dominio stesso, ad esempio (.*\.?example\.org)per example.come sub.example.com.
trkoch,

3
Qualche idea su come adattarlo a IIS 7?
Segna il

Ma non è sconfiggere lo scopo? Cosa impedirebbe a un utente malintenzionato di falsificare il valore dell'intestazione Origin?
Grégory Joseph,

1
@ GrégoryJoseph Access-Control-Allow-Origin non significa nascondere le risorse a qualcuno che può richiederlo. Si tratta di impedire a un sito dannoso di avere utenti finali che chiamano il tuo sito. Nel caso dei file di font, questo può effettivamente limitare il collegamento a caldo dei font, perché loro (mozilla / firefox) non hanno fatto lo stesso per altre risorse (js, css, ecc.) È al di là di me.
Tracker1,

@trkoch, c'è un bug nel tuo regex, lo permetterà anche subexample.com. Dovresti cambiarlo in:((.*\.)?example\.org)
bluesmoon il

65

Ecco come riecheggiare l'intestazione Origin se corrisponde al tuo dominio con Nginx, questo è utile se vuoi servire un carattere su più sottodomini:

location /fonts {
    # this will echo back the origin header
    if ($http_origin ~ "example.org$") {
        add_header "Access-Control-Allow-Origin" $http_origin;
    }
}

Non riesco a capire come sia diverso da: add_header Access-Control-Allow-Origin *; Ti interessa spiegare?
Anoyz,

questo restituirà un'intestazione che autorizza il browser a inviare solo richieste dal dominio specificato. se immagino direi che il browser potrebbe autorizzare il contenuto di un altro dominio caricato su quella pagina per accedere in altro modo al server.
martedì

7
@Anoyz per prima cosa potrebbe esserci una maggiore sicurezza in cui "Consenti *" non è consentito, ma un nome host specificato e corrispondente per l'intestazione consentita funziona. Un esempio qui, se si desidera inviare informazioni di autorizzazione tra domini, non è possibile utilizzare "Consenti *"
TCC

3
In .in esempio.org viene interpretato come un valore dato che si tratta di un'espressione regolare? In tal caso, ciò consentirebbe erroneamente un TLD esempio-org personalizzato?
stuckj,

1
Un regex corretto dovrebbe essere "^example\.org$"perché devi assicurarti che un hacker non possa sfuggire al tuo regex con subdomainexample.org(usa ^) o example.orgevil(usa $) o examplezorg(scappa \.)
zeg

27

Ecco cosa ho fatto per un'applicazione PHP che è stata richiesta da 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 l'origine richiedente è consentita dal mio server, restituisce $http_originse stesso come valore Access-Control-Allow-Origindell'intestazione anziché restituire un *carattere jolly.


20

C'è uno svantaggio di cui dovresti essere a conoscenza: non appena esegui l'outsourcing dei file su un CDN (o qualsiasi altro server che non consente lo scripting) o se i tuoi file vengono memorizzati nella cache su un proxy, alterando la risposta in base a "Origine" l'intestazione della richiesta non funzionerà.


4
Potresti approfondire questo, o indicarci un posto in cui possiamo cercare maggiori informazioni? Sto cercando di fare proprio questo con Limelight e spero che ti sbagli. Uno dei nostri tecnici ha detto che fintanto che il nostro seed server CDN invia l'intestazione, la stessa CDN lo invierà. Devo ancora provarlo
BT

12
Se le cache o le CDN rappresentano un problema, utilizzare l'intestazione Vary per indicare alla cache / CDN di mantenere risposte separate per valori di intestazione della richiesta Origin diversi. Includeresti un'intestazione come "Vary: Origin" nella tua risposta. La cache / CDN quindi sa che dovrebbe inviare una risposta a una richiesta con intestazione "Origin: foo.example.com " e una risposta diversa a una richiesta con intestazione "Origin: bar.example.com ".
Sean,

Vary: Origin non è supportato da Akamai , uno dei più grandi CDN disponibili ... Maggiori dettagli disponibili anche qui
Brad Parks

20

Per più domini, nel tuo .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>

4
Questo frammento funziona perfettamente per me. Ma non capisco cosa fa: D
Karl Adler,

2
questo ha funzionato per me, anche se ho dovuto aggiungere un '^' cioè ... SetEnvIf Origin "^ http (s)?: // (www \.)?
gypsyDev

Fa praticamente lo stesso di stackoverflow.com/a/14034228/209139 . È solo che la sintassi .htaccess è molto più difficile da leggere rispetto a PHP. Header set Vary Originsarebbe una bella aggiunta a questa risposta.
TRiG

1
Grazie mille per il tuo aiuto
Cool Perfectionist,

2
Ho dovuto cambiare AccessControlAllowOrigin=$0$1in AccessControlAllowOrigin=$0. Altrimenti, non ha funzionato per le origini HTTPS. http://example.comè uscito correttamente, ma https://example.comè uscito come https://example.coms, con un extra salla fine.
TRiG

17

Per gli utenti di Nginx consentire CORS per più domini. Mi piace l'esempio di @ marshall anche se le sue risposte corrispondono solo a un dominio. Per abbinare un elenco di domini e sottodomini questo regex semplifica il lavoro con i caratteri:

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

Ciò farà eco solo alle intestazioni "Access-Control-Allow-Origin" che corrispondono all'elenco di domini specificato.


Pensa di aver bisogno di bloccare quel regex alla fine con \ z perché altrimenti a domain3.com.badhacker.com sarebbe consentito l'accesso.
Dft

@dft Definiamo $ alla fine che lo fa
Adriano Rosa,

Scusate, intendevo nell'esempio generale, l'attuale post di @AdrianoRosa fa la stessa cosa di \ z
dft il


13

Ecco una soluzione per l'app Web Java, basata sulla risposta di yesthatguy.

Sto usando Jersey REST 1.x

Configurare web.xml per essere a conoscenza di Jersey REST e 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>

Ecco il codice per 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;
}

}

Il link sopra è scaduto, puoi aggiungerne uno nuovo o aggiornare la risposta con maggiori dettagli, grazie
RajKumar Samala

Ho aggiunto maggiori dettagli, spero che questo aiuti
duvo

12

Come accennato in precedenza, Access-Control-Allow-Origindovrebbe essere univoco e Varydovrebbe essere impostato su Originse si è dietro un CDN (Content Delivery Network).

Parte rilevante della mia configurazione 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';
}

ha set $corsuna sorta di significato nascosto, o è solo specifico per la tua conifg? sembra che possa essere omesso insieme al secondoif
mikezter il

Esatto, può essere omesso se questa è l'unica condizione che testate per impostare le intestazioni, ne avevo molte nella mia configurazione.
hernvnc,

9

Forse mi sbaglio, ma per quanto posso vedere Access-Control-Allow-Originha un "origin-list"parametro as.

Per definizione an 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 da questo, sostengo che sono ammesse origini diverse e dovrebbero essere separate dallo spazio .


2
Questa sembra un'interpretazione corretta delle specifiche; detto ciò, le specifiche non sembrano essere pienamente supportate dagli attuali browser (ad esempio, ho appena provato questo su Firefox 17.0 e ho confermato che non funzionerà).
Rick Riensche,

7
La sezione delle specifiche CORS5.1 Access-Control-Allow-Origin Response Header afferma che l' elenco delle origini
maxpolk,

2
Come ho detto in un commento sulla mia risposta, fa parte di una nota degli implementatori, non di un requisito RFC 2119. La risposta "corretta" è assolutamente usare valori delimitati da spazi. Il problema è semplicemente che le implementazioni sono incomplete e quindi la risposta "corretta" non funziona necessariamente. Dovrebbe, ma non lo fa. Tuttavia, in futuro, poiché le implementazioni miglioreranno, questo potrebbe cambiare.
Bob Aman,

8

Per le applicazioni ExpressJS è possibile utilizzare:

app.use((req, res, next) => {
    const corsWhitelist = [
        'https://domain1.example',
        'https://domain2.example',
        'https://domain3.example'
    ];
    if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    }

    next();
});

questo consentirà tutte le altre chiamate da una chiamata successiva ...
Ievgen Naida

@IevgenNaida Quindi? Qual è il problema?
eyecatchUp

7

Ho faticato a configurarlo per un dominio che esegue HTTPS, quindi ho pensato di condividere la soluzione. Ho usato la seguente direttiva nel mio file httpd.conf :

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

Passa example.comal tuo nome di dominio. Aggiungi questo all'interno <VirtualHost x.x.x.x:xx>nel tuo file httpd.conf . Nota che se hai VirtualHostun suffisso (ad es. :80), Questa direttiva non si applicherà a HTTPS, quindi dovrai anche andare su / etc / apache2 / sites-available / default-ssl e aggiungere la stessa direttiva in quel file, all'interno della <VirtualHost _default_:443>sezione.

Dopo aver aggiornato i file di configurazione, è necessario eseguire i seguenti comandi nel terminale:

a2enmod headers
sudo service apache2 reload

Mi piace questa opzione e l'ho combinata / modificata con l'implementazione di @George. A volte i server non hanno a2enmod disponibile, quindi tutto ciò che devi fare è controllare il tuo httpd.conf principale per vedere se la riga: LoadModule headers_module modules / mod_headers.so non è commentata.
Mike Kormendy,

La mia origine aveva un numero di porta, quindi ho modificato l'espressione regolare per includerla: ^http(s)?://(.+\.)?example\.com(:\d+)?$
indiv

5

In caso di problemi con i caratteri, utilizzare:

<FilesMatch "\.(ttf|ttc|otf|eot|woff)$">
    <IfModule mod_headers>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>
</FilesMatch>

3

Un approccio più flessibile consiste nell'utilizzare le espressioni di Apache 2.4. Puoi abbinare domini, percorsi e praticamente ogni altra variabile di richiesta. Sebbene la risposta inviata sia sempre *, gli unici richiedenti che la ricevono sono comunque quelli che soddisfano i requisiti. L'uso dell'intestazione della richiesta Origin(o di qualsiasi altra) nell'espressione fa sì che Apache la fonda automaticamente nell'intestazione della Varyrisposta, in modo che la risposta non venga riutilizzata per un'origine diversa.

<IfModule mod_headers.c>
    <If "%{HTTP:Host} =~ /\\bcdndomain\\.example$/i && %{HTTP:Origin} =~ /\\bmaindomain\\.example$/i">
        Header set Access-Control-Allow-Origin "*"
    </If>
</IfModule>

2
Sono venuto qui perché alcuni browser non accettano *credenziali come Login. Quindi sarà meglio se si passa il nome host corrispondente invece di *.
KeitelDOG,

@KeitelDOG come si fa a catturare dinamicamente l'origine corretta e rispedirla quando ci sono più origini, invece di ripetere il codice per ciascun dominio? Sembra che potrebbe essere possibile con le espressioni, ma i documenti non mi sono chiari.
Walf,

In realtà il mio vero problema era perché laravel non ha restituito l' Access-Control-Allow-Originintestazione per la OPTIONSrichiesta di verifica preliminare che controlla le intestazioni per vedere se il server consente questa origine. L'ho risolto. Quindi *non è stato il vero problema per me. Tuttavia, alcuni browser non accettano le *credenziali, quindi quando un'app Web invia una richiesta Cross-Origin, DEVONO specificare l' HTTP_ORIGINintestazione a cui è possibile accedere in modo dinamico con la variabile Originin .htaccessper Apache o $_SERVER['HTTP_ORIGIN'];in PHP. Comunque la tua soluzione è buona in quanto consente tutte le origini, ma meno sicura
KeitelDOG

Ma 2 cose da ricordare è che 1) Fornire *consente tutto. 2) HOST è diverso da ORIGIN. HOST è l'attuale 'TARGET HOST` che viene passato all'intestazione della richiesta. Ma ORIGIN è quello INITIAL HOSTche invia la richiesta al TARGET HOST. Pertanto, nel tuo codice, ORIGIN HOSTviene ignorato e mai utilizzato. Vedi le risposte sopra e vedrai come usano i ORIGINvalori per aggiungerli Access-Control-Allow-Origin.
KeitelDOG

@KeitelDOG *Non consente a tutti perché l'utilizzo Origindell'intestazione della richiesta nell'espressione fa sì che Apache la fonda automaticamente nell'intestazione della Varyrisposta, a meno che non venga utilizzata req_novary('Origin')(probabilmente indesiderabile). I browser sanno che potrebbero ottenere una risposta diversa per una diversa Origine se il valore inviato non supera il test, l' Access-Control-Allow-Originintestazione non viene mai impostata.
Walf

3

Codice PHP:

$httpOrigin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : null;
if (in_array($httpOrigin, [
    'http://localhost:9000', // Co-worker dev-server
    'http://127.0.0.1:9001', // My dev-server
])) header("Access-Control-Allow-Origin: ${httpOrigin}");
header('Access-Control-Allow-Credentials: true');

2

HTTP_ORIGIN non è utilizzato da tutti i browser. Quanto è sicuro HTTP_ORIGIN? Per me risulta vuoto in FF.
Ho i siti a cui autorizzo l'accesso al mio sito tramite un ID sito, quindi controllo il mio DB per il record con quell'ID e ottengo il valore della colonna SITE_URL (www.tuoSite.com).

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

Anche se l'invio su un ID sito valido, la richiesta deve provenire dal dominio elencato nel mio DB associato a tale ID sito.


2

Ecco un'opzione estesa per apache che include alcune delle definizioni dei font più recenti e pianificate:

<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>

2

Per facilitare l'accesso a più domini per un servizio ASMX, ho creato questa funzione nel file global.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();
    }
}

Ciò consente anche la gestione CORS del OPTIONSverbo.


2

Esempio di codice PHP per la corrispondenza dei sottodomini.

if( preg_match("/http:\/\/(.*?)\.yourdomain.example/", $_SERVER['HTTP_ORIGIN'], $matches )) {
        $theMatch = $matches[0];
        header('Access-Control-Allow-Origin: ' . $theMatch);
}

2

Per una copia / incolla abbastanza semplice per le applicazioni .NET, ho scritto questo per abilitare CORS dall'interno di un global.asaxfile. Questo codice segue i consigli forniti nella risposta attualmente accettata, riflettendo nella risposta qualsiasi origine restituita nella richiesta. Ciò raggiunge effettivamente '*' senza usarlo.

La ragione di ciò è che abilita molteplici altre funzionalità CORS , inclusa la possibilità di inviare un AJAX XMLHttpRequest con l'attributo 'withCredentials' impostato su '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" , "*");
    }
}

1

E un'altra risposta in Django. Per avere una vista singola consentire CORS da più domini, ecco il mio codice:

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

AWS Lambda / API Gateway

Per informazioni su come configurare origini multiple su Serverless AWS Lambda e API Gateway - anche se una soluzione piuttosto grande per qualcosa che si potrebbe pensare dovrebbe essere abbastanza semplice - vedi qui:

https://stackoverflow.com/a/41708323/1624933


Al momento non è possibile configurare origini multiple in API Gateway, vedere qui: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html ), ma la raccomandazione (in la risposta sopra) è:

  • ispeziona l'intestazione Origin inviata dal browser
  • verificalo con una whitelist di origini
  • se corrisponde, restituisce Origin in arrivo come intestazione Access-Control-Allow-Origin, altrimenti restituisce un segnaposto (origine predefinita).

La semplice soluzione sta ovviamente abilitando ALL (*) in questo modo:

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
        },
        body: JSON.stringify([{

Ma potrebbe essere meglio farlo sul lato API Gateway (vedi 2 ° link sopra).


2
Access-Control-Allow-Credentials: truenon è consentito con caratteri jolly Access-Control-Allow-Origin: *. Imposta <origin>invece uno specifico .
Tom,

@Tom, sì, non sono sicuro del perché fosse lì, non riesco a ricordare, ma avrei potuto copiarlo dalle impostazioni predefinite aggiunte su AWS? Grazie per averlo sottolineato però.
timhc22,

0

La risposta dell'assistenza di Google sulla pubblicazione di annunci su SSL e la grammatica nella stessa RFC sembrerebbe indicare che è possibile delimitare lo spazio degli URL. Non sono sicuro di quanto sia ben supportato questo nei diversi browser.


"pubblicazione di annunci tramite ssl" si collega alla specifica w3.org/TR/cors/#access-control-allow-origin-response-header che aggiunge una nota, "In pratica la produzione con elenco di origine o null è più limitata Piuttosto che consentire un elenco di origini separato da spazi, è una singola origine o la stringa "null".
spazm

Mentre è importante notare quel dettaglio, quando una specifica dice "In pratica", non significa che sia valido solo per farlo in quel modo. Ciò significa che se lo fai in questo modo, potresti riscontrare problemi perché la maggior parte degli implementatori implementa la specifica in modo errato o incompleto. La specifica consente un elenco di origini separato da spazi, che puoi vedere qui nell'EBNF sotto origin-list: tools.ietf.org/html/rfc6454#section-7.1
Bob Aman,

0

Se provi così tanti esempi di codice come me per farlo funzionare usando CORS, vale la pena ricordare che devi prima svuotare la cache per provare se funziona davvero, simile a problemi come quando le vecchie immagini sono ancora presenti, anche se è cancellato sul server (perché è ancora salvato nella cache).

Ad esempio CTRL + SHIFT + DELin Google Chrome per eliminare la cache.

Questo mi ha aiutato a usare questo codice dopo aver provato molte .htaccesssoluzioni pure e questo sembrava l'unico funzionante (almeno per me):

    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>

Si noti inoltre che è ampiamente diffuso che molte soluzioni affermano che è necessario digitare, Header set ...ma lo è Header add .... Spero che questo aiuti qualcuno che ha gli stessi problemi per alcune ore come me.


0

La risposta di seguito è specifica per C #, ma il concetto dovrebbe essere applicabile a tutte le diverse piattaforme.

Per consentire le richieste di origine incrociata da un'API Web, è necessario consentire le richieste di opzione all'applicazione e aggiungere l'annotazione di seguito a livello di controller.

[EnableCors (UrlString, Header, Method)] Ora le origini possono essere passate solo come stringa. Quindi, se si desidera passare più di un URL nella richiesta, passarlo come valore separato da virgola.

UrlString = " https: //a.hello.com,https: //b.hello.com "


0

È possibile specificare una sola origine per l'intestazione Access-Control-Allow-Origin. Ma puoi impostare l'origine nella tua risposta in base alla richiesta. Inoltre, non dimenticare di impostare l'intestazione Vary. In PHP farei quanto segue:

    /**
     * Enable CORS for the passed origins.
     * Adds the Access-Control-Allow-Origin header to the response with the origin that matched the one in the request.
     * @param array $origins
     * @return string|null returns the matched origin or null
     */
    function allowOrigins($origins)
    {
        $val = $_SERVER['HTTP_ORIGIN'] ?? null;
        if (in_array($val, $origins, true)) {
            header('Access-Control-Allow-Origin: '.$val);
            header('Vary: Origin');

            return $val;
        }

        return null;
    }

  if (allowOrigins(['http://localhost', 'https://localhost'])) {
      echo your response here, e.g. token
  }

-2

Possiamo anche impostarlo nel file Global.asax per l'applicazione Asp.net.

protected void Application_BeginRequest(object sender, EventArgs e)
    {

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

    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.