Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Çoklu origin (domain) için CORS izni vermenin programatik yolu ve Express.js'te dinamik origin validasyon pattern'im

pixero

Üye
Katılım
14 Mart 2026
Mesajlar
23
Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve bulduğum çözümü paylaşmak istiyorum. API'mi birden fazla domain'den (örneğin, farklı müşteri sitelerinden) çağırmam gerekiyordu ve her yeni domain için sunucuyu restart etmek, CORS whitelist'ini güncellemek can sıkıcı bir hal almıştı. "Bu işin daha dinamik bir yolu olmalı" diye düşünüp kolları sıvadım.

🔥 Karşılaştığım Sorun

Klasik Express.js CORS yapılandırması genelde şöyle oluyor:
JavaScript:
const cors = require('cors');
app.use(cors({
    origin: ['https://musteri1.com', 'https://musteri2.com'] // Sabit liste
}));
Her yeni müşteri domain'i eklediğimde bu listeyi güncellemem ve uygulamayı yeniden başlatmam gerekiyordu. Bu, hem geliştirme sürecini yavaşlatıyor hem de canlı sistemde downtime'a sebep oluyordu. Ayrıca, origin kontrolünü daha esnek, mesela bir veritabanı sorgusu veya pattern eşleştirme ile yapmak istiyordum.

💡 Dinamik Origin Validasyonu Fikri

Çözüm olarak, `cors` paketinin `origin` seçeneğine sadece bir dizi değil, bir fonksiyon da verebileceğimi fark ettim. Bu fonksiyon, gelen isteğin `origin` header'ını alıp, bu origin'e izin verilip verilmeyeceğine dair bir boolean (true/false) veya callback döndürebiliyor. İşte benim kullandığım en temiz çözüm:

JavaScript:
const cors = require('cors');
const allowedOriginPatterns = [
    /^https:\/\/musteri-\d+\.firma\.com$/, // musteri-1.firma.com, musteri-2.firma.com gibi
    /^https:\/\/staging\.(.)\.projem\.com$/, // staging alt domain'leri
    'https://kesin-izinli-domain.com' // Tekil domain
];

// Dinamik kontrol fonksiyonu
const corsOptionsDelegate = function (req, callback) {
    const requestOrigin = req.header('Origin');
    let corsOptions;

    // Eğer origin yoksa (örneğin aynı origin'den istek) veya pattern'lerden biri ile eşleşiyorsa izin ver
    if (!requestOrigin || allowedOriginPatterns.some(pattern => {
        if (typeof pattern === 'string') {
            return pattern === requestOrigin;
        } else if (pattern instanceof RegExp) {
            return pattern.test(requestOrigin);
        }
        return false;
    })) {
        corsOptions = { origin: true }; // İstek origin'ine izin ver
    } else {
        corsOptions = { origin: false }; // İzni reddet
    }
    callback(null, corsOptions);
};

app.use(cors(corsOptionsDelegate));

🚀 Pattern'imi Bir Veritabanı İle Güçlendirmek

Ancak benim asıl ihtiyacım, izin verilen domain'leri bir veritabanında (örneğin, müşteri kayıtlarında) tutmaktı. İşte o zaman bu pattern'i bir adım öteye taşıdım. Fonksiyonu, veritabanından gelen dinamik bir liste ile çalışacak hale getirdim.

JavaScript:
const corsOptionsDelegate = async function (req, callback) {
    const requestOrigin = req.header('Origin');
    let corsOptions;

    if (!requestOrigin) {
        // Origin yoksa, belki same-origin isteği veya bir API tool'u. Dikkatli ol!
        return callback(null, { origin: false }); // Veya güvenli bir şekilde true da yapılabilir.
    }

    try {
        // Veritabanından izinli domain listesini çek (cache'leyebilirsin!)
        const allowedDomains = await MusteriModel.find({ apiIzinli: true }, 'domain').lean();
        const domainList = allowedDomains.map(m => m.domain);

        // Gelen origin, listemizde var mı?
        if (domainList.includes(requestOrigin)) {
            corsOptions = { origin: true };
        } else {
            corsOptions = { origin: false };
            // İstersen log atabilirsin: console.warn(`CORS Reddedildi: ${requestOrigin}`);
        }
    } catch (error) {
        // DB hatasında güvenli tarafta kal, izin verme.
        console.error('CORS DB Hatası:', error);
        corsOptions = { origin: false };
    }

    callback(null, corsOptions);
};

// Middleware'i async fonksiyonla kullanmak için
app.use((req, res, next) => {
    cors(corsOptionsDelegate)(req, res, next);
});

Bu yapı sayesinde, yeni bir müşteri kaydolduğunda veya mevcut bir müşteri için API erişimini açtığımda, sadece veritabanındaki `apiIzinli` alanını güncellemem yeterli oluyor. Bir sonraki istekte CORS middleware'imiz bu değişikliği otomatik olarak uyguluyor. Canlı sistemi restart etmeye gerek kalmıyor!

Siz backend geliştirirken CORS yönetimi için nasıl bir yol izliyorsunuz? Özellikle mikroservis veya multi-tenant mimarilerde benzer bir sorunla karşılaştınız mı? Veritabanı sorgusunu performans için nasıl cache'lersiniz? Yorumlarda deneyimlerinizi paylaşın!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri