web-dev-qa-db-fra.com

CORS: impossible d'utiliser un caractère générique dans Access-Control-Allow-Origin lorsque l'indicateur d'accréditations est true

J'ai une configuration impliquant

Serveur frontend (Node.js, domaine: localhost: 3000) <---> Backend (Django, Ajax, domaine: localhost: 8000)

Navigateur <- webapp <- Node.js (Servir l’application)

Navigateur (webapp) -> Ajax -> Django (Servir les demandes ajax POST)

Maintenant, mon problème ici concerne la configuration CORS utilisée par la webapp pour passer des appels Ajax au serveur principal. En chrome, je continue à recevoir

Impossible d'utiliser un caractère générique dans Access-Control-Allow-Origin lorsque l'indicateur d'informations d'identification est true.

ne fonctionne pas non plus sur Firefox.

Ma configuration de Node.js est:

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

Et dans Django j'utilise ce middlewareavec cela

La webapp fait des requêtes en tant que telles:

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

Ainsi, les en-têtes de requête envoyés par l'application Web ressemblent à ceci:

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="***"

Et voici l'en-tête de réponse:

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

Où est-ce que je vais mal?!

Edit 1: J'utilise chrome --disable-web-security, mais je veux maintenant que les choses fonctionnent réellement.

Edit 2: Réponse:

Donc, solution pour moi Django-cors-headers config:

CORS_Origin_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_Origin_WHITELIST = (
    'http://localhost:3000' # Here was the problem indeed and it has to be http://localhost:3000, not http://localhost:3000/
)
245
ixaxaar

Cela fait partie de la sécurité, vous ne pouvez pas le faire. Si vous souhaitez autoriser les informations d'identification, votre Access-Control-Allow-Origin ne doit pas utiliser *. Vous devrez spécifier le protocole exact + domaine + port. Pour référence voir ces questions:

  1. sous-domaines, ports et protocoles génériques avec caractère générique d’Access-Control-Allow-Origin
  2. Partage de ressources d'origine croisée avec des informations d'identification

En outre, * est trop permissif et empêcherait l'utilisation des informations d'identification. Définissez donc http://localhost:3000 ou http://localhost:8000 comme en-tête Autoriser l’origine.

213
user568109

Si vous utilisez un middleware CORS et que vous voulez envoyer withCredential boolean true, vous pouvez configurer CORS comme suit:

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

Si vous utilisez express, vous pouvez utiliser le paquet cors pour permettre à CORS de le faire plutôt que d'écrire votre middleware;

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

app.use(cors());

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

essayez-le:

const cors = require('cors')

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

}
app.use(cors(corsOptions));
7
Iron shield

Pour le développement de Chrome, l’installation de cette extension supprimera cette erreur spécifique:

Access to XMLHttpRequest at 'http://192.168.1.42:8080/sockjs-node/info?t=1546163388687' 
from Origin 'http://localhost:8080' has been blocked by CORS policy: The value of the 
'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' 
when the request's credentials mode is 'include'. The credentials mode of requests 
initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Après l’installation, assurez-vous d’ajouter votre motif d’URL à l’icône Intercepted URLs en cliquant sur l’icône AddOn (CORS, verte ou rouge). et en remplissant la zone de texte appropriée. Un exemple de modèle d'URL à ajouter ici qui fonctionnera avec http://localhost:8080 serait: *://*

3
eriel marimon

Si vous souhaitez autoriser toutes les origines et conserver les informations d'identification vraies, cela a fonctionné pour moi:

app.use(cors({
  Origin: function(Origin, callback){
    return callback(null, true);
  },
  optionsSuccessStatus: 200,
  credentials: true
}));
3
Squirrl

Cela fonctionne pour moi en développement, mais je ne peux pas vous dire qu'en production, c'est simplement une façon différente de faire le travail qui n'a pas encore été mentionné, mais probablement pas la meilleure. Quoi qu'il en soit, voici:

Vous pouvez obtenir l'origine à partir de la demande, puis l'utiliser dans l'en-tête de la réponse. Voici à quoi ça ressemble dans express:

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', req.header('Origin') );
  next();
});

Je ne sais pas à quoi cela ressemblerait avec votre configuration python, mais cela devrait être facile à traduire.

0
Renaud