483 Stimmen

Access-Control-Allow-Origin Platzhalter für Subdomänen, Ports und Protokolle

Ich versuche, CORS für alle Subdomänen, Ports und Protokolle zu aktivieren.

Ich möchte zum Beispiel eine XHR-Anfrage von http://sub.mywebsite.example:8080/ まで https://www.mywebsite.example/ *

In der Regel möchte ich Anfragen aus den entsprechenden Herkunftsländern aktivieren (und auf diese beschränken):

//*.mywebsite.example:*/*

381voto

monsur Punkte 42927

Die CORS-Spezifikation ist ein Alles-oder-Nichts-Modell. Sie unterstützt nur * , null oder das genaue Protokoll + Domäne + Port: http://www.w3.org/TR/cors/#access-control-allow-origin-response-header

Ihr Server muss den Herkunfts-Header mithilfe des Regex validieren, und dann können Sie den Herkunftswert in der Access-Control-Allow-Origin Antwort-Header.

280voto

Noyo Punkte 4534

Basierend auf DaveRandom's Antwort Ich habe auch ein wenig herumgespielt und eine etwas einfachere Apache-Lösung gefunden, die das gleiche Ergebnis liefert ( Access-Control-Allow-Origin wird dynamisch auf das aktuelle spezifische Protokoll + Domäne + Port gesetzt), ohne dass irgendwelche Rewrite-Regeln verwendet werden:

SetEnvIf Origin ^(https?://.+\.mywebsite\.example(?::\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"

Und das war's.

Diejenigen, die CORS auf der übergeordneten Domäne aktivieren möchten (z. B. mywebsite.example ) sowie alle seine Unterdomänen können den regulären Ausdruck in der ersten Zeile einfach durch diesen ersetzen:

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

Anmerkung: Für Spezifikationseinhaltung und korrektes Caching-Verhalten, fügen Sie IMMER die Vary: Origin Antwort-Header für CORS-aktivierte Ressourcen, auch für Nicht-CORS-Anfragen und solche von einem nicht zugelassenen Ursprung (siehe Beispiel warum ).

66voto

DaveRandom Punkte 85940

Verwenden Sie @Noyo's Lösung anstelle von diesem. Es ist einfacher, übersichtlicher und wahrscheinlich viel leistungsfähiger unter Last.

DIE URSPRÜNGLICHE ANTWORT WURDE HIER NUR ZU HISTORISCHEN ZWECKEN HINTERLASSEN!


Ich habe ein wenig mit diesem Problem herumgespielt und bin zu diesem wiederverwendbaren .htaccess (oder httpd.conf ) eine Lösung, die mit Apache funktioniert:

<IfModule mod_rewrite.c>
<IfModule mod_headers.c>
    # Define the root domain that is allowed
    SetEnvIf Origin .+ ACCESS_CONTROL_ROOT=yourdomain.example

    # 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
</IfModule>
</IfModule>

Stellen Sie einfach die ACCESS_CONTROL_ROOT Variable am Anfang des Blocks auf Ihre Root-Domäne und es wird das Echo der Origin: Header-Wert der Anfrage zurück an den Client in der Access-Control-Allow-Origin: Antwort-Header-Wert, wenn er mit Ihrer Domäne übereinstimmt.

Beachten Sie auch, dass Sie mit sub.mydomain.example als die ACCESS_CONTROL_ROOT und beschränkt die Ursprünge auf sub.mydomain.example y *.sub.mydomain.example (d. h. es muss nicht der Bereich Root sein). Die Elemente, die variieren dürfen (Protokoll, Port), können durch Ändern des URI-Matching-Teils der Regex gesteuert werden.

53voto

Pratap Koritala Punkte 1407

Ich beantworte diese Frage, weil die akzeptierte Antwort kann folgendes nicht tun

  1. Regex-Gruppierung ist eine Performance-Hit was nicht notwendig ist.
  2. kann nicht übereinstimmen primär Domäne und funktioniert nur für die Unterdomäne.

Zum Beispiel: Es sendet keine CORS-Header für http://mywebsite.example während die Arbeiten für http://somedomain.mywebsite.example/

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"

Um dies für Ihre Website zu aktivieren, setzen Sie einfach Ihre Website an die Stelle von mywebsite.example in der obigen Apache-Konfiguration.

Mehrere Standorte zulassen:

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

Validierung Nach der Bereitstellung:

Die folgende curl-Antwort sollte nach der Änderung die Kopfzeile "Access-Control-Allow-Origin" enthalten.

curl -X GET -H "Origin: http://site1.example" --verbose http://site2.example/query

17voto

Lars Punkte 5635

Ich brauchte eine reine PHP-Lösung, also nur für den Fall, dass jemand sie auch braucht. Es nimmt einen zulässigen Eingabe-String wie "*.example.com" und gibt den Server-Namen des Anfrage-Headers zurück, wenn die Eingabe übereinstimmt.

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

Und hier sind die Testfälle für einen phpunit-Datenanbieter:

//    <description>                            <allowed>          <input>                   <expected>
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',   'a.b.example.com',        'a.b.example.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'),

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X