- Konu sahibi
- #1
Nginx CORS yapılandırması
Nginx üzerinde CORS açmak için API yanıtlarına
Access-Control-Allow-Origin ve gerekiyorsa preflight istekleri için Access-Control-Allow-Methods ile Access-Control-Allow-Headers başlıklarını eklemelisiniz. En güvenli yaklaşım, * kullanmak yerine izin verilen frontend origin değerini açıkça tanımlamaktır. Aşağıdaki örnek, tarayıcıda yanıt okuma iznini yalnız https://app.example.com origin’ine verir ve /api/ yolunda çalışır.CORS nasıl çalışır?
Tarayıcı, farklı origin'e yapılan istekte
Origin başlığını gönderir. Origin; protokol, alan adı ve portun birleşimidir. Örneğin https://app.example.com ile https://api.example.com farklı origin kabul edilir.Basit bir
GET isteğinde tarayıcı doğrudan isteği gönderebilir. PUT/DELETE gibi yöntemler, JSON içerik türü veya safelist dışında başlıklar kullanıldığında ise önce OPTIONS yöntemiyle preflight isteği gönderilir. Nginx bu isteğe izin verilen origin, yöntem ve başlıkları bildiren başarılı bir yanıt vermelidir.Çalıştırılabilir temel Nginx örneği
Önce
http bloğuna origin eşlemesini ekleyin. Bu bölüm server bloğunun dışında, ana Nginx yapılandırmasındaki http { ... } bölümü içinde bulunmalıdır:
NGINX:
map $http_origin $cors_origin {
default "";
"https://app.example.com" $http_origin;
}
Ardından aşağıdaki location parçasını,
api.example.com için TLS sertifikası ve HTTPS dinlemesi zaten çalışan mevcut server bloğuna ekleyin. Bu parça tek başına bir HTTPS sunucusu kurmaz:
NGINX:
location /api/ {
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Vary Origin always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
if ($request_method = OPTIONS) {
return 204;
}
proxy_pass http://127.0.0.1:8080;
}
Örnek, Linux’ta Nginx yapılandırmasını değiştirme yetkisi olan yönetici ve
/api/ yolunu karşılayan yerel 8080 uygulaması varsayar. Önce çalışan yapılandırmanın yedeğini alın. Dosyayı kaydettikten sonra kontrol edin:- Yapılandırma sözdizimini kontrol edin:
sudo nginx -t. Başarılı sonuçtasyntax is okvetest is successfulmesajları görülmelidir. - Nginx'i yeniden yükleyin:
sudo nginx -s reload. - Preflight yanıtını test edin:
curl -i -X OPTIONS https://api.example.com/api/test -H "Origin: https://app.example.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: Content-Type, Authorization". - Yanıtta 204, doğru Allow-Origin ve gereken yöntem/başlık izinlerini doğrulayın. Ardından gerçek GET yanıtını ve izinli/izinsiz origin’den tarayıcı erişimini ayrı sınayın; yalnız OPTIONS başarısı yeterli değildir.
Buradaki
proxy_pass satırı isteği uygulama sunucusuna aktarır. Bu proxy_pass biçimi /api/ önekini uygulamaya koruyarak iletir. HTTPS arayüzün HTTP API’ye çağrısı karma içerik engeline takılabileceği için dış API örneği HTTPS olarak verildi.Hangi ayarı seçmelisiniz?
CORS başlıklarını yalnızca gerçekten dış origin'den erişilecek API konumuna eklemek, tüm siteye açmaktan daha kontrollüdür.
| İhtiyaç | Access-Control-Allow-Origin | Credentials |
|---|---|---|
| Herkese açık, oturumsuz API | * | Kullanmayın |
| Belirli frontend adresi | https://app.example.com | Gerekirse açıkça true |
| Cookie veya oturum kullanan API | Tek ve açık origin | true |
Bu politika kimlik doğrulama veya CSRF koruması değildir; izin verilmeyen istemcinin ağ isteğini sunucuda otomatik reddetmez.
Cookie veya tarayıcı kimlik bilgisi kullanılacaksa
Access-Control-Allow-Origin: * kullanmayın. Bu durumda açık origin ve aynı location içinde ayrıca şu başlık gerekir:
NGINX:
add_header Access-Control-Allow-Credentials "true" always;
İstemci tarafında da
fetch çağrısının credentials: "include" kullanması gerekir. Kimlik bilgisi gerekmiyorsa bu başlığı eklemeyin.Sık yapılan hatalar
Access-Control-Allow-Origin değerine tam origin yerine yalnızca alan adı yazmak hatalıdır; protokol ve gerekiyorsa port da bulunmalıdır. İzin verilen origin'i gelen Origin başlığından koşulsuz yansıtmak da güvenli değildir; yalnızca tanımlı allowlist değerlerini eşleştirin.Uygulama sunucusu zaten CORS başlıkları ekliyorsa Nginx'in aynı başlıkları tekrar eklemesi tarayıcıda “multiple CORS header” hatasına yol açabilir. Bu durumda CORS politikasını tek katmanda yönetin veya proxy yanıtındaki çakışan başlıkları kaldırmadan önce hangi katmanın sorumlu olduğunu belirleyin. Yeni location içindeki add_header tanımları, varsayılan miras modelinde üst seviyedeki başlıkları devralmayı kesebilir. Mevcut güvenlik başlıklarını koruyun; kurulu sürümdeki miras davranışını kontrol edin; testte mutlaka gerçek API yanıtını ve
OPTIONS yanıtını ayrı ayrı inceleyin.Sık sorulan sorular
CORS hatası yalnızca tarayıcıda oluşuyorsa sunucu çalışmıyor mu?
Hayır. API,
curl ile yanıt verse bile tarayıcı CORS başlıklarını denetler. Tarayıcı geliştirici araçlarında özellikle OPTIONS isteğinin durum kodunu ve yanıt başlıklarını kontrol edin.Nginx yerine uygulamada CORS tanımlamak gerekir mi?
Tek bir katmanda tanımlamak yeterlidir. Reverse proxy tüm istemci yanıtlarını kontrol ediyorsa Nginx uygun bir yerdir; uygulama da ek başlık gönderiyorsa yinelenen başlık oluşmadığından emin olun.
Son düzenleme: