it-swarm.com.de

wie wird Access-Control-Allow-Origin umgangen?

Ich mache einen Ajax-Aufruf an meinen eigenen Server auf einer Plattform, die diese Ajax-Aufrufe verhindern sollen (aber ich brauche es, um die Daten von meinem Server abzurufen, um die abgerufenen Daten aus der Datenbank meines Servers anzuzeigen). Mein Ajax-Skript ist Wenn es funktioniert, kann es die Daten an das PHP-Skript meines Servers senden, damit es verarbeitet werden kann ..__ Die verarbeiteten Daten können jedoch nicht zurückgegeben werden, da sie durch "Access-Control-Allow-Origin" blockiert werden.

Ich habe keinen Zugriff auf die Quelle/den Kern dieser Plattform. Daher kann ich das Skript, das es mir nicht erlaubt, nicht entfernen. (P/S Ich habe die Google Chrome-Konsole verwendet und diesen Fehler gefunden).

Der Ajax-Code wie unten gezeigt:

 $.ajax({
     type: "GET",
     url: "http://example.com/retrieve.php",
     data: "id=" + id + "&url=" + url,
     dataType: 'json',   
     cache: false,
     success: function(data)
      {
        var friend = data[1];              
        var blog = data[2];           
        $('#user').html("<b>Friends: </b>"+friend+"<b><br> Blogs: </b>"+blog);

      } 
  });

oder gibt es einen JSON-äquivalenten Code zum obigen ajax-Skript? Ich denke, JSON ist erlaubt.

Ich hoffe jemand kann mir helfen.

172
ETAN

Setzen Sie das auf retrieve.php:

header('Access-Control-Allow-Origin: *');  

Beachten Sie, dass dadurch der CORS-Schutz effektiv deaktiviert wird und Ihre Benutzer Angriffen ausgesetzt sind. Wenn Sie nicht ganz sicher sind, dass Sie all origins zulassen müssen, sollten Sie dies auf einen spezifischeren Ursprung festlegen:

header('Access-Control-Allow-Origin: https://www.example.com')
336
Rafay

Okay, aber Sie alle wissen, dass * ein Platzhalter ist und Cross Site Scripting von jeder Domäne aus erlaubt?

Sie möchten mehrere Access-Control-Allow-Origin-Header für jede Website senden, die dies zulässt - leider wird es offiziell nicht unterstützt, mehrere Access-Control-Allow-Origin-Header zu senden oder mehrere Ursprünge anzugeben.

Sie können dieses Problem lösen, indem Sie den Ursprung überprüfen und diesen in der Kopfzeile zurückschicken, sofern dies zulässig ist:

$Origin = $_SERVER['HTTP_Origin'];
$allowed_domains = [
    'http://mysite1.com',
    'https://www.mysite2.com',
    'http://www.mysite2.com',
];

if (in_array($Origin, $allowed_domains)) {
    header('Access-Control-Allow-Origin: ' . $Origin);
}

Das ist viel sicherer. Möglicherweise möchten Sie den Abgleich bearbeiten und ihn mit einem regulären Ausdruck oder einer ähnlichen Funktion in eine manuelle Funktion umwandeln. Zumindest wird dies nur 1 Header zurücksenden, und Sie werden sicher sein, von dem die Anfrage stammt. Bitte beachten Sie, dass alle HTTP-Header can gefälscht werden können, aber dieser Header dient dem Schutz des Clients. Schützen Sie Ihre eigenen Daten nicht mit diesen Werten. Wenn Sie mehr wissen wollen, lesen Sie ein wenig über CORS und CSRF.

Warum ist es sicherer?

Wenn Sie den Zugriff von anderen Standorten aus erlauben, ermöglicht Ihre eigene vertrauenswürdige Site das High-Jacking von Sitzungen. Ich gehe mit einem kleinen Beispiel - Image Facebook erlaubt eine Wildcard-Herkunft - das heißt, Sie können Ihre eigene Website irgendwo erstellen und sie zum Feuern bringen AJAX Anrufe (oder offene Iframes) für Facebook. Das bedeutet, dass Sie sich die eingeloggten Informationen des Facebook eines Besuchers Ihrer Website holen können. Schlimmer noch - Sie können POST-Anforderungen in Skripts schreiben und Daten auf Facebook posten - nur während sie Ihre Website durchsuchen.

Seien Sie vorsichtig, wenn Sie die ACAO-Header verwenden!

268
Rob Quist

Warnung , Chrome (und andere Browser) werden sich beschweren, dass mehrere ACAO-Header gesetzt sind, wenn Sie einige der anderen Antworten befolgen.

Der Fehler wird ungefähr wieXMLHttpRequest cannot load ____. The 'Access-Control-Allow-Origin' header contains multiple values '____, ____, ____', but only one is allowed. Origin '____' is therefore not allowed access.

Versuche dies:

$http_Origin = $_SERVER['HTTP_Origin'];

$allowed_domains = array(
  'http://domain1.com',
  'http://domain2.com',
);

if (in_array($http_Origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_Origin");
}
28
user3638471

Ich habe dieses Problem beim Aufruf eines MVC3-Controllers behoben.

Response.AddHeader("Access-Control-Allow-Origin", "*"); 

vor meinem

return Json(model, JsonRequestBehavior.AllowGet);

Und auch mein $.ajax hat sich beschwert, dass er Content-Type -Header in meinem Ajax-Aufruf nicht akzeptiert. Deshalb habe ich ihn kommentiert, da ich weiß, dass seine JSON an die Action übergeben wird.

Hoffentlich hilft das.

7
Atif Rehman

am besten wäre es, einzelne Domains zuzulassen. Seien Sie vorsichtig mit dem http: //:

     header('Access-Control-Allow-Origin: http://www.foo.com', false);
     header('Access-Control-Allow-Origin: http://www.foo2.com', false));
5

Haben Sie tatsächlich versucht, den Access-Control-Allow-Origin-Header der von Ihrem Server gesendeten Antwort hinzuzufügen? Wie Access-Control-Allow-Origin: *?

2
Daniel Brockman

Es ist eine wirklich schlechte Idee, * zu verwenden, sodass Sie Cross-Site-Scripting weit hinter sich lassen können. Grundsätzlich möchten Sie immer Ihre eigene Domäne haben, die sich auf Ihre aktuellen SSL-Einstellungen und optional auf weitere Domänen bezieht. Sie möchten auch, dass alle als ein Header gesendet werden. Im Folgenden wird immer Ihre eigene Domäne im selben SSL-Bereich wie die aktuelle Seite autorisiert. Sie kann optional auch eine beliebige Anzahl zusätzlicher Domänen enthalten. Sie werden alle als eine Kopfzeile gesendet und die vorherige (n) überschreiben, falls bereits etwas anderes gesendet wurde, um zu vermeiden, dass der Browser über mehrere Kopfzeilen der Zugriffskontrolle grollt.

class CorsAccessControl
{
    private $allowed = array();

    /**
     * Always adds your own domain with the current ssl settings.
     */
    public function __construct()
    {
        // Add your own domain, with respect to the current SSL settings.
        $this->allowed[] = 'http'
            . ( ( array_key_exists( 'HTTPS', $_SERVER )
                && $_SERVER['HTTPS'] 
                && strtolower( $_SERVER['HTTPS'] ) !== 'off' ) 
                    ? 's' 
                    : null )
            . '://' . $_SERVER['HTTP_Host'];
    }

    /**
     * Optionally add additional domains. Each is only added one time.
     */
    public function add($domain)
    {
        if ( !in_array( $domain, $this->allowed )
        {
            $this->allowed[] = $domain;
        }
    /**
     * Send 'em all as one header so no browsers grumble about it.
     */
    public function send()
    {
        $domains = implode( ', ', $this->allowed );
        header( 'Access-Control-Allow-Origin: ' . $domains, true ); // We want to send them all as one shot, so replace should be true here.
    }
}

Verwendungszweck:

$cors = new CorsAccessControl();

// If you are only authorizing your own domain:
$cors->send();

// If you are authorizing multiple domains:
foreach ($domains as $domain)
{
    $cors->add($domain);
}
$cors->send();

Du hast die Idee.

0
mopsyd