Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorundan ve nasıl temiz bir çözüm bulduğumdan bahsedeceğim. Bir microservices projesinde, her servisin kendi başına CORS politikası tanımlaması tam bir kaosa ve 'Access-Control-Allow-Origin' hatalarının hiç bitmemesine neden oluyordu. Her yeni servis eklediğimde veya domain değişikliğinde tüm servisleri tek tek güncellemek zorunda kalıyordum. İşte bu dertten kurtulmak için API Gateway seviyesinde merkezi bir CORS politikası nasıl uygularız, onu anlatacağım.
Dağınıklık Sorunu ve Gateway'e Karar Veriş
İlk başta her microservice'in kendi Node.js (Express) veya Laravel uygulamasında CORS middleware'ini yapılandırıyordum. Bu, geliştirme aşamasında belki idare eder gibiydi ama production'da, özellikle farklı ekiplerin farklı servisler geliştirdiği bir ortamda, tutarlılığı sağlamak imkansız hale gelmişti. Bir ekip header'ı unutuyor, diğeri farklı bir domain ekliyor... Kafayı yemek üzereydim.
Çözüm: Tüm CORS kontrolünü, microservices'in önünde duran ve tüm isteklerin giriş kapısı olan API Gateway katmanına taşımak. Bu sayede CORS kurallarını sadece BİR YERDE, merkezi olarak yönetebiliyorsunuz. Ben gateway olarak NGINX kullanmayı tercih ettim, ancak Kong, KrakenD veya AWS API Gateway gibi çözümlerde de prensip aynı.
NGINX API Gateway'de Merkezi CORS Konfigürasyonu
NGINX'in `nginx.conf` veya `/etc/nginx/sites-available/` altındaki konfigürasyon dosyanızda, API Gateway'inizi tanımladığınız `location` bloğuna aşağıdaki gibi CORS header'larını ekleyebilirsiniz. Bu, gateway'den geçen TÜM isteklere uygulanacak.
Bu yapılandırmanın güzel yanı, artık arka plandaki hiçbir Laravel veya Node.js servisinin CORS ile uğraşmasına gerek kalmaması. Onlar sadece iş mantığına odaklanıyor. Hatta güvenlik için, bu servislerin sadece internal network'ten (gateway'den) gelen istekleri kabul edecek şekilde yapılandırılmasını da öneririm.
Ortam Değişkenleri ile Dinamik Yönetim
Production, staging ve development ortamlarında izin verilen origin'ler farklı olabilir. NGINX konfigürasyonunu da dinamik hale getirmek için `map` directive'ini kullanabilir veya configuration templating (Ansible, Docker envsubst) araçlarından faydalanabilirsiniz. Aşağıda basit bir `map` örneği:
Bu yöntemle, izin verilen origin listesini tek bir yerde (NGINX config'inde) güncelleyerek tüm sistemi etkileyebiliyorsunuz. Deploy sırasında yaşadığım stres inanılmaz azaldı.
Sonuç olarak, microservices mimarisinde CORS'u her servise dağıtmak yerine API Gateway'de merkezileştirmek, yönetilebilirliği, güvenliği ve geliştirici deneyimini ciddi anlamda iyileştiriyor. Siz bu sorunu nasıl çözdünüz? Farklı bir gateway teknolojisi (Kong, AWS API Gateway) kullanıyorsanız, orada CORS'u nasıl yapılandırdınız? Yorumlarda deneyimlerinizi paylaşın, tartışalım!
İlk başta her microservice'in kendi Node.js (Express) veya Laravel uygulamasında CORS middleware'ini yapılandırıyordum. Bu, geliştirme aşamasında belki idare eder gibiydi ama production'da, özellikle farklı ekiplerin farklı servisler geliştirdiği bir ortamda, tutarlılığı sağlamak imkansız hale gelmişti. Bir ekip header'ı unutuyor, diğeri farklı bir domain ekliyor... Kafayı yemek üzereydim.
Çözüm: Tüm CORS kontrolünü, microservices'in önünde duran ve tüm isteklerin giriş kapısı olan API Gateway katmanına taşımak. Bu sayede CORS kurallarını sadece BİR YERDE, merkezi olarak yönetebiliyorsunuz. Ben gateway olarak NGINX kullanmayı tercih ettim, ancak Kong, KrakenD veya AWS API Gateway gibi çözümlerde de prensip aynı.
NGINX'in `nginx.conf` veya `/etc/nginx/sites-available/` altındaki konfigürasyon dosyanızda, API Gateway'inizi tanımladığınız `location` bloğuna aşağıdaki gibi CORS header'larını ekleyebilirsiniz. Bu, gateway'den geçen TÜM isteklere uygulanacak.
NGINX:
server {
listen 80;
server_name api.benimfirmam.com;
# Tüm OPTIONS (Preflight) isteklerini burada handle et
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://www.benimuygulamam.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000; # Önbellek süresi (20 gün)
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204; # No Content
}
# Gerçek istekler (GET, POST vb.) için CORS header'ları
add_header 'Access-Control-Allow-Origin' 'https://www.benimuygulamam.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
# İsteği ilgili microservice'e yönlendir (örneğin bir upstream bloğuna)
proxy_pass http://microservices_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Bu yapılandırmanın güzel yanı, artık arka plandaki hiçbir Laravel veya Node.js servisinin CORS ile uğraşmasına gerek kalmaması. Onlar sadece iş mantığına odaklanıyor. Hatta güvenlik için, bu servislerin sadece internal network'ten (gateway'den) gelen istekleri kabul edecek şekilde yapılandırılmasını da öneririm.
Production, staging ve development ortamlarında izin verilen origin'ler farklı olabilir. NGINX konfigürasyonunu da dinamik hale getirmek için `map` directive'ini kullanabilir veya configuration templating (Ansible, Docker envsubst) araçlarından faydalanabilirsiniz. Aşağıda basit bir `map` örneği:
NGINX:
# http bloğu içinde
map $http_origin $cors_origin {
default "";
"~^https?://localhost(:\d+)?$" "$http_origin";
"~^https://staging.benimuygulamam.com$" "$http_origin";
"~^https://www.benimuygulamam.com$" "$http_origin";
}
server {
...
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $cors_origin;
...
}
add_header 'Access-Control-Allow-Origin' $cors_origin;
...
}
}
Bu yöntemle, izin verilen origin listesini tek bir yerde (NGINX config'inde) güncelleyerek tüm sistemi etkileyebiliyorsunuz. Deploy sırasında yaşadığım stres inanılmaz azaldı.
Sonuç olarak, microservices mimarisinde CORS'u her servise dağıtmak yerine API Gateway'de merkezileştirmek, yönetilebilirliği, güvenliği ve geliştirici deneyimini ciddi anlamda iyileştiriyor. Siz bu sorunu nasıl çözdünüz? Farklı bir gateway teknolojisi (Kong, AWS API Gateway) kullanıyorsanız, orada CORS'u nasıl yapılandırdınız? Yorumlarda deneyimlerinizi paylaşın, tartışalım!