509 Stimmen

CORS: Kann kein Platzhalter in Access-Control-Allow-Origin verwenden, wenn das credentials-Flag auf true gesetzt ist

Ich habe ein Setup, das Folgendes umfasst

Frontend-Server (Node.js, Domain: localhost:3000) <---> Backend (Django, Ajax, Domain: localhost:8000)

Browser <-- webapp <-- Node.js (Die App bereitstellen)

Browser (webapp) --> Ajax --> Django (Ajax-POST-Anfragen bereitstellen)

Mein Problem hier liegt jetzt beim CORS-Setup, das die Web-App verwendet, um Ajax-Aufrufe an den Backend-Server zu tätigen. In Chrome erhalte ich immer

Kann kein Platzhalter in Access-Control-Allow-Origin verwenden, wenn das Flag für Berechtigungen true ist.

Funktioniert auch nicht in Firefox.

Mein Node.js-Setup ist:

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'http://localhost:8000/');
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
};

Und in Django verwende ich dieses Middleware zusammen mit diesem

Die Web-App sendet Anfragen wie folgt:

$.ajax({
    type: "POST",
    url: 'http://localhost:8000/blah',
    data: {},
    xhrFields: {
        withCredentials: true
    },
    crossDomain: true,
    dataType: 'json',
    success: successHandler
});

Also sehen die Anfrageheader, die die Web-App sendet, wie folgt aus:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"
Access-Control-Allow-Methods: 'GET,PUT,POST,DELETE'
Content-Type: application/json 
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: csrftoken=***; sessionid="***"

Und hier ist der Antwort-Header:

Access-Control-Allow-Headers: Content-Type,*
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
Content-Type: application/json

Wo mache ich einen Fehler?!

Bearbeiten 1: Ich habe chrome --disable-web-security benutzt, aber möchte jetzt, dass die Dinge tatsächlich funktionieren.

Bearbeiten 2: Antwort:

Also die Lösung für mich ist die django-cors-headers Konfiguration:

CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
    'http://localhost:3000' # Hier lag tatsächlich das Problem und es muss http://localhost:3000 heißen, nicht http://localhost:3000/
)

373voto

user568109 Punkte 46053

Dies ist ein Teil der Sicherheit, den Sie nicht tun können. Wenn Sie Anmeldeinformationen zulassen möchten, darf Ihr Access-Control-Allow-Origin nicht * verwenden. Sie müssen das genaue Protokoll + Domain + Port angeben. Zu Referenzzwecken siehe diese Fragen:

  1. Access-Control-Allow-Origin Wildcard-Subdomains, Ports und Protokolle
  2. Cross Origin Resource Sharing mit Anmeldeinformationen

Außerdem ist * zu allgemein und würde die Verwendung von Anmeldeinformationen zunichte machen. Setzen Sie also http://localhost:3000 oder http://localhost:8000 als den erlaubten Ursprung-Header.

101voto

Hamid Punkte 2682

Wenn Sie das CORS-Middleware verwenden und withCredential auf true setzen möchten, können Sie CORS wie folgt konfigurieren:

var cors = require('cors');    
app.use(cors({credentials: true, origin: 'http://localhost:3000'}));

68voto

Christoph Hansen Punkte 742

Erweiterung der Idee von @Renaud, bietet cors jetzt einen sehr einfachen Weg, um dies zu tun:

Von der offiziellen Dokumentation von cors hier gefunden:

" origin: Konfiguriert den Access-Control-Allow-Origin CORS-Header. Mögliche Werte: Boolean - setzen Sie origin auf true, um den Ursprung der Anfrage widerzuspiegeln, wie von req.header('Origin') definiert, oder setzen Sie ihn auf false, um CORS zu deaktivieren. "

Daher machen wir einfach folgendes:

const app = express();
const corsConfig = {
    credentials: true,
    origin: true,
};
app.use(cors(corsConfig));

Zu guter Letzt denke ich, dass es erwähnenswert ist, dass es Anwendungsfälle gibt, in denen wir plattformübergreifende Anfragen von jedermann erlauben möchten; zum Beispiel beim Aufbau einer öffentlichen REST-API.

22voto

Iron shield Punkte 329

Probieren Sie es aus:

const cors = require('cors')

const corsOptions = {
    origin: 'http://localhost:4200',
    credentials: true,

}
app.use(cors(corsOptions));

17voto

Bulkan Punkte 2507

Wenn du express verwendest, kannst du das cors Paket verwenden, um CORS zu erlauben, anstatt dein eigenes Middleware zu schreiben;

var express = require('express')
, cors = require('cors')
, app = express();

app.use(cors());

app.get(function(req,res){ 
  res.send('hello');
});

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