- Konu sahibi
- #1
Access-Control-Allow-Origin nedir?
.htaccess içinde Access-Control-Allow-Origin başlığını göndermek için Apache’nin mod_headers modülünü kullanabilirsiniz. Herkese açık bir kaynak için en küçük örnek şöyledir:
Kod:
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "*"
</IfModule>
Bu başlık, diğer CORS koşulları da sağlandığında tarayıcıya yanıtı başka origin'deki JavaScript'e açma izni bildirir. Sunucudaki erişim yetkisini değiştirmez. Ancak
* tüm kaynakları açar ve çerez ya da kimlik bilgisi gerektiren isteklerle birlikte kullanılamaz. Özel bir siteye izin vermek için * yerine açıkça belirlenmiş origin kullanın:
Kod:
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "https://example.com"
</IfModule>
Buradaki origin; protokol, alan adı ve gerekiyorsa porttan oluşur. Sonunda eğik çizgi bulunmaz.
https://example.com ile http://example.com farklı origin’lerdir.Apache ön koşulları ve uygulama
Ön koşul, Apache’de
mod_headers modülünün etkin olması ve sunucunun .htaccess içinde Header yönergesine izin vermesidir. Dosya, izin verilen dizinin kökünde veya ilgili alt dizinde bulunmalıdır. Bu bölüm Apache içindir; NGINX .htaccess okumaz. Header için FileInfo override izni veya uygun AllowOverrideList gerekir. Değiştirmeden önce mevcut dosyanın geri dönüş kopyasını saklayın.- CORS başlığını eklemek istediğiniz dizindeki
.htaccessdosyasını açın. - Kaynak herkese açık olacaksa aşağıdaki yapılandırmayı, özel bir site olacaksa
*yerine gerçek origin’i kullanarak ekleyin. - Değişikliği kaydedip tarayıcı geliştirici araçlarında ilgili isteğin yanıt başlıklarını açın.
- Yanıtta
Access-Control-Allow-Origin: *veya beklediğiniz origin görünüyorsa temel ayar çalışıyordur.
İstek hâlâ CORS hatası veriyorsa önce yanıt başlığının gerçekten eklenip eklenmediğini ve
.htaccess dosyasının doğru dizinde olduğunu kontrol edin. Sunucu 500 Internal Server Error döndürüyorsa yönerge izni ve sözdizimi için Apache hata günlüğünü inceleyin. Örnekteki IfModule modül yoksa bloğu sessizce atlayabilir; 500 görülmemesi modülün etkin olduğunu kanıtlamaz.always kullanılması, hata yanıtları gibi normal olmayan yanıt türlerinde de başlığın eklenmesine yardımcı olur. Apache’nin onsuccess ve always başlık tabloları farklıdır; always, diğer tablonun mutlak üst kümesi değildir. Uygulama veya proxy aynı başlığı ekliyorsa yalnız set kullanmak çift başlığı otomatik çözmez; başlığı tek katmanda üretin.Hangi CORS parçası neyi yapar?
| Parça | Görevi | Tek başına sağlamadığı şey |
|---|---|---|
| Access-Control-Allow-Origin | İzin verilen origin'i bildirmek | API yetkilendirmesi ve preflight'ın başarılı işlenmesi |
| Access-Control-Allow-Methods/Headers | Ön istekte gerçek metot ve başlık izni | İşlemin sunucu tarafından kabul edilmesi |
| Vary: Origin | Origin'e göre değişen yanıtı önbelleğe bildirmek | Yanlış veya herkese açık önbellek politikasını düzeltmek |
Origin’e göre kontrollü izin verme
Birden fazla belirli siteye izin vermek istiyorsanız gelen
Origin değerini doğrulamadan doğrudan yanıt başlığına kopyalamayın. Apache ortamında sınırlı bir listeyi SetEnvIf ile eşleştirip yalnızca eşleşen origin için başlık ekleyebilirsiniz:
Kod:
<IfModule mod_headers.c>
SetEnvIf Origin "^(https://(?:www\.)?example\.com)$" CORS_ORIGIN=$1
Header always set Access-Control-Allow-Origin "%{CORS_ORIGIN}e" env=CORS_ORIGIN
Header always merge Vary "Origin"
</IfModule>
Bu örnek
mod_setenvif modülünü de gerektirir. Yalnız iki örnek origin kabul edilir; yakalanan değer CORS_ORIGIN ortam değişkenine atanır. İstek başlığı kendiliğinden aynı adlı ortam değişkeni değildir. Vary: Origin, önbelleğe yanıtın Origin'e göre değişebildiğini bildirir. Bu bilgi eşleşmeyen isteğin yanıtında da bulunur; merge, mevcut Vary değerlerini ezmeden Origin'i ekler. Oturum yanıtlarının cache politikası ayrıca doğru olmalıdır. Eşleşmeyen origin’ler için Access-Control-Allow-Origin gönderilmez ve tarayıcı yanıtı JavaScript’e açmaz.Kullanıcı oturumu veya çerez gönderilecekse sunucunun ayrıca
Access-Control-Allow-Credentials: true başlığını döndürmesi ve Access-Control-Allow-Origin değerinin * olmaması gerekir. Bu durumda yalnızca gerçekten güvendiğiniz origin’leri listeleyin; CORS, sunucunun kimlik doğrulamasını kaldırmaz, sadece tarayıcının yanıtı başka bir origin’deki betiğe açıp açmayacağını belirler.OPTIONS ön isteği ve diğer başlıklar
Tarayıcı, özel başlık veya bazı HTTP yöntemleri kullanılan isteklerden önce
OPTIONS ön isteği gönderebilir. Yalnızca Access-Control-Allow-Origin eklemek bu isteği her zaman tamamlamaz. Uygulamanızın ihtiyaç duyduğu yöntem ve başlıkları açıkça tanımlayın:
Kod:
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "https://example.com"
Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
Header always merge Vary "Origin"
</IfModule>
Bu yapılandırma, sunucunun ilgili
OPTIONS isteğine gerçekten başarılı bir yanıt vermesini sağlamaz. Uygulama veya Apache yönlendirmesi OPTIONS isteğini işleyemiyorsa, Allow-Methods ve Allow-Headers başlıkları bulunsa bile tarayıcı asıl isteği göndermeyebilir. Bu nedenle ön isteğin HTTP durum kodunu ve yanıt başlıklarını ayrıca kontrol edin.Sık yapılan hatalar
Access-Control-Allow-Originbaşlığını istemci JavaScript’ine eklemeye çalışmak: Bu başlık sunucu yanıtında bulunmalıdır.*değerini çerezli veya kimlik bilgili isteklerle kullanmak: Tarayıcı bu birleşimi kabul etmez.- Origin’e portu dahil etmemek:
https://example.com:8443, portsuz origin ile aynı değildir. - Her gelen
Origindeğerini doğrulamadan yansıtmak: Bu, izin kapsamını kontrolsüz biçimde genişletebilir. - CORS hatasını sunucu erişim yetkisi sanmak: CORS yalnızca tarayıcı davranışıdır; API’nin kimlik doğrulaması ve yetkilendirmesi ayrıca korunmalıdır.
Sık sorulan sorular
Birden fazla örneği aynı dosyaya eklemeli miyim?
Hayır. Sabit origin, yıldız ve izin listesi birbirinin alternatifidir. Gerçek ihtiyacınız olan bir yaklaşımı seçin; aynı yanıt için birden çok Access-Control-Allow-Origin değeri üretmeyin.
Yapılandırma görünürde doğruyken başlık neden iki kez geliyor?
CORS başlığı hem
.htaccess hem sanal host, uygulama veya proxy tarafından ekleniyor olabilir. Tek bir katmanda üretilecek şekilde diğer tanımı kaldırın; farklı değerlerin birlikte gönderilmesi tarayıcıda yine CORS hatasına yol açabilir.