CORS: Kimlik bilgileri bayrağı doğru olduğunda Access-Control-Allow-Origin'de joker karakter kullanılamaz


296

İçeren bir kurulumum var

Ön uç sunucusu (Node.js, etki alanı: localhost: 3000) <---> Arka uç (Django, Ajax, etki alanı: localhost: 8000)

Tarayıcı <- webapp <- Node.js (Uygulamayı sun)

Tarayıcı (webapp) -> Ajax -> Django (ajax POST istekleri sun)

Şimdi, burada benim sorun webapp arka uç sunucusuna Ajax çağrıları yapmak için kullandığı CORS kurulum ile. Kromda alıyorum

Kimlik bilgileri bayrağı doğru olduğunda Access-Control-Allow-Origin'de joker karakter kullanılamaz.

firefox üzerinde de çalışmaz.

Node.js kurulumum:

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

Ve Django'da bununla birlikte bu katman yazılımını kullanıyorum

Webapp şu şekilde istekte bulunur:

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

Dolayısıyla, web uygulamasının gönderdiği istek başlıkları şöyle görünür:

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

Ve işte yanıt başlığı:

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

Nerede yanlış gidiyorum ?!

Düzenleme 1: Kullanıyorum chrome --disable-web-security, ancak şimdi işlerin gerçekten çalışmasını istiyorum.

Düzenleme 2: Yanıt:

Yani, benim için çözüm django-cors-headersyapılandırma:

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

1
Benim için localhost: http olmadan 3000, şunun gibi: CORS_ORIGIN_WHITELIST = ('localhost: 3000',)
Andrei

Yani bir PC'de ön uç ve arka uç geliştirmeyi mi kullanıyorsunuz?
fanhualuojin154873

nasıl farklı PC ön ve arka uç?
fanhualuojin154873

@ixaxaar neden http ile çalıştığını söylüyorsun? hepimiz sadece `` localhost: 3000 '' çalışıyoruz.
244boy

@ 244boy evet noktası değildir http, öyle /sonunda. Http'yi atlamanın işe yarayacağını sanıyorum, ancak birkaç yıldır bu şeyler üzerinde gerçekten çalışmadım, bu yüzden şimdi ne işe yaradığını bilmiyorum!
ixaxaar

Yanıtlar:


247

Bu güvenliğin bir parçası, bunu yapamazsınız. Kimlik bilgilerine izin vermek istiyorsanız Access-Control-Allow-Originkullanmamalısınız *. Tam protokol + etki alanı + bağlantı noktasını belirtmeniz gerekir. Referans için şu sorulara bakın:

  1. Access-Control-Allow-Origin joker karakter alt alanları, bağlantı noktaları ve protokolleri
  2. Kimlik Bilgileri ile Çapraz Kaynak Kaynağı Paylaşımı

Ayrıca *çok izin vericidir ve kimlik bilgilerinin kullanımını bozabilir. Böylece http://localhost:3000veya http://localhost:8000başlangıç ​​izni başlığı olarak ayarlayın .


45
Ancak, birden fazla alan varsa ne olur?
aroth

13
@aroth Alan adlarının bir listesini verebilirsiniz. İlgili soru: stackoverflow.com/questions/1653308/…
user568109

13
@ user568109 "Ayrıca *çok izin vericidir ve kimlik bilgilerinin kullanımını bozabilir" diyebilir misiniz ?
Hugo Wood

12
İstek mobil cihazdan geliyorsa, Cordova'da olduğu gibi "tam alan adı" nedir?
Christian

8
@Christian biraz eski, ama hala merak eden biri varsa, bu sorun sadece tarayıcılarda çalışan uygulamalar için olur, çünkü bu hata tarayıcı tarafından güvenlik nedeniyle atılır. Mobil uygulama, postacı veya http istemcisini istekte bulunmak için kullanan diğer arka uç kodları gibi diğer istemcilerde bu sorun olmaz, bu nedenle kaynak ve tam etki alanı hakkında endişelenmenize gerek yoktur .
Alisson

32

CORS ara katman yazılımı kullanıyorsanız ve withCredentialboole true değerini göndermek istiyorsanız, CORS'yi şu şekilde yapılandırabilirsiniz:

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

16

Kullanıyorsanız express, Cware'e ara katman yazılımınızı yazmak yerine izin vermek için cors paketini kullanabilirsiniz ;

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

app.use(cors());

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

12
Ah, şimdi bu daha uygun, ancak sonuç aynı :( BTW, kullanıyorumapp.use(cors({credentials: true}));
ixaxaar

1
Test edilen bu Django CORS ara katman yazılımına bakmak isteyebilirsiniz .
Bulkan

1
Yani iki Django aracınız var mı? Yalnızca django-cors-headeruygulamayı kullanırdım . Eklemek emin olun localhost için CORS_ORIGIN_WHITELISTayar ve sette CORS_ALLOW_CREDENTIALSiçinTrue
Bulkan

1
Evet dostum, boşuna önce sahip olduğu denenmiş CORS_ORIGIN_ALLOW_ALL = True, CORS_ORIGIN_WHITELIST = ( 'localhost' )ve CORS_ALLOW_CREDENTIALS = True ben bu başlıkları almak:Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://localhost:3000/ Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE Content-Type: application/json
ixaxaar

5
Bu belgeleri okuduktan sonra: github.com/expressjs/corsuse i bu yapılandırmayı kullanarak: app.use (cors ({credentials: true, origin: ' localhost: 3001 '})); benim için çalışıyor.
allel

11

dene:

const cors = require('cors')

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

}
app.use(cors(corsOptions));

6

Tüm kökenlere izin vermek ve kimlik bilgilerini doğru tutmak istiyorsanız, bu benim için çalıştı:

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

@TSlegaitis Haha evet, bu yüzden tüm kökenler için çalışıyor ancak kimlik bilgilerini koruyor. Güvenlik için tavsiye etmem ama işe yarıyor.
Squirrl

2

(Düzenle) Önceden önerilen eklenti artık kullanılamıyor, diğerini deneyebilirsiniz


Chrome'da geliştirme amacıyla, bu eklentiyi yüklemek o hatadan kurtulacaktır:

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.

Intercepted URLsYükledikten sonra AddOn'un ( CORS , yeşil veya kırmızı) simgesine tıklayarak ve uygun metin kutusunu doldurarak url deseninizi eklediğinizden emin olun . Buraya eklenecek örnek bir URL modeli şöyledir http://localhost:8080:*://*


Kurduktan hemen sonra anladım, herhangi bir fikir?
Jalil

Benim için çalıştı. Başka benzer eklentileriniz varsa, bunu denemeden önce kaldırmanız gerekir.
FilippoG

lütfen kırık bağlantıyı düzeltin
Luk Aron

Orijinal eklenti kaldırılmış gibi görünüyor, üstte bir (Düzenle) olarak yeni bir öneri ekledim
eriel marimon

1

Bu benim için geliştirmede işe yarıyor, ancak üretimde henüz işin bitirilmesinin farklı bir yolu olduğunu, ancak muhtemelen en iyisinin olmadığını tavsiye edemem. Neyse burada:

Kökeni istekten alabilir, ardından yanıt başlığında kullanabilirsiniz. İşte böyle ifade:

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

Python kurulumunuzla neye benzeyeceğini bilmiyorum ama çevirmesi kolay olmalı.


Mozilla Dev Docs , izin verilen kaynağı isteğe bağlı olarak değiştirme fikrini genişletir. 'Vary: Origin' HTTP yanıt üstbilgisi ve beyaz listeye izin verilen alanların eklenmesi önerilir.
Ramzis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.