Cross-Origin (CORS) İsteklerinde Çerez Gönderim Sorununu Çözmek için Kapsamlı Kılavuz

Sunucunun çerezi doğru şekilde ayarladığı (tarayıcı yanıtında görünür) ancak sonraki isteklerde tarayıcının bu çerezi sunucuya geri göndermediği bir senaryo ile karşılaştıysanız, bu kılavuz sizin için. Bu sorun neredeyse her zaman projenizin ön yüzü ve arka yüzü iki farklı alan adında veya portta olduğunda ortaya çıkar — örneğin, ön yüz app.example.com ve API api.example.com üzerinde.

Bu Neden Olur?

Modern tarayıcılar, CSRF saldırılarını ve oturum ele geçirmeyi önlemek için iki katı güvenlik politikası uygular:

  1. CORS Politikası: Varsayılan olarak, tarayıcı, sunucu açıkça izin vermedikçe, alanlar arası isteklerin kimlik bilgileri (çerezler gibi) içermesine izin vermez.
  2. SameSite Politikası: Chrome 80'den itibaren, çerezler varsayılan olarak SameSite=Lax davranışıyla ele alınır; bu, SameSite=None ile açıkça tanımlanmadıkça alanlar arası isteklerde gönderilmeyecekleri anlamına gelir.

Önemli nokta, bu sorunu çözmek için hem istemci hem de sunucu tarafının doğru şekilde yapılandırılması gerektiğidir. Sadece bir tarafı değiştirmek yeterli değildir.

Adım 1: Sunucunun Doğru Yapılandırılması

Sunucu Tarafında Üç Altın Kural

Kural 1 — Kimlik Bilgilerini Etkinleştirin: Sunucu yanıt başlığı aşağıdaki değeri içermelidir:

Access-Control-Allow-Credentials: true

Kural 2 — Joker Karakter Kullanmayın: Kimlik bilgileri etkinleştirildiğinde, Access-Control-Allow-Origin başlığında * joker karakterini kullanamazsınız. Ön yüzün tam alan adresini tam olarak belirtmelisiniz:

Access-Control-Allow-Origin: https://app.example.com

Kural 3 — Çerez Özellikleri: Çerez iki özellikle ayarlanmalıdır: SameSite=None ve Secure. Bu iki özellik olmadan, tarayıcı çerezi depolar ancak alanlar arası isteklerde asla göndermez.

Node.js (Express) Örnek Kodu

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors({
  origin: 'https://app.example.com', // Ön yüzün tam alan adı, / olmadan
  credentials: true
}));

app.post('/login', (req, res) => {
  res.cookie('session_token', 'abc123', {
    httpOnly: true,   // Çereze JavaScript erişimini engeller
    secure: true,     // Yalnızca HTTPS üzerinden gönderilir
    sameSite: 'none', // Cross-Origin isteklerinde gönderime izin verir
    maxAge: 24 * 60 * 60 * 1000
  });
  res.json({ message: 'Giriş başarılı' });
});

PHP Örnek Kodu

<?php
// Ön yüzün tam alan adını belirtin, * değil
header("Access-Control-Allow-Origin: https://app.example.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");

// Preflight isteğine yanıt ver
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

// Çerezi gerekli özelliklerle ayarlama
setcookie('session_token', 'abc123', [
    'expires'  => time() + 86400,
    'path'     => '/',
    'secure'   => true,      // Zorunlu
    'httponly' => true,
    'samesite' => 'None'     // Cross-Origin için zorunlu
]);

Not: Laravel kullanıyorsanız, config/cors.php dosyasında supports_credentials değerini true olarak ayarlayın ve ön yüz alan adını allowed_origins dizisine ekleyin.

Adım 2: İstemcinin (Ön Yüz) Doğru Yapılandırılması

Sunucu yapılandırması tam olsa bile, bu isteğin "kimlik bilgileri ile" olduğunu istemci tarafında açıkça bildirmediğiniz sürece tarayıcı çerezleri göndermez.

Fetch API Kullanımı

fetch('https://api.example.com/user/profile', {
  method: 'GET',
  credentials: 'include'  // Bu satır sorunu çözmenin anahtarıdır
})
  .then(res => res.json())
  .then(data => console.log(data));

Axios Kullanımı

// Belirli bir istek için
axios.get('https://api.example.com/user/profile', {
  withCredentials: true
});

// Veya tüm proje için genel olarak
axios.defaults.withCredentials = true;

Sorun Giderme Kontrol Listesi

Yukarıdakileri uyguladıktan sonra sorun devam ederse, bu maddeleri sırayla kontrol edin:

  • Her iki taraf da HTTPS üzerinde mi? Secure özelliği, çerezin yalnızca şifreli bağlantılar üzerinde çalıştığı anlamına gelir. Siteniz HTTP üzerindeyse, tarayıcı çerezi kabul etmez. (İstisna: localhost üzerindeki geliştirme ortamı)
  • Origin adresi tam olarak doğru mu? Access-Control-Allow-Origin adresi, tarayıcıda gördüğünüz URL ile tam olarak eşleşmelidir. www farkı veya sondaki eğik çizgi / bile başarısızlığa neden olur.
  • OPTIONS isteği başarılı mı? Tarayıcı geliştirici araçlarının Network sekmesinde, Preflight isteğini (OPTIONS yöntemiyle) kontrol edin. Bu istek, 200 veya 204 kodu ve doğru CORS başlıkları ile yanıtlanmalıdır.
  • Çerez depolandı mı? Tarayıcıda, DevTools ← Application ← Cookies yoluna gidin ve çerezin Secure ve SameSite=None özellikleriyle depolandığından emin olun.
  • Bir proxy veya aracı güvenlik duvarınız var mı? Bazen Cloudflare veya Nginx gibi web sunucuları başlıkları yeniden yazar. Bunların yapılandırmasını da kontrol edin.

Özet

Alanlar arası isteklerde çerez göndermek, üç faktörün koordinasyonunu gerektirir: Access-Control-Allow-Credentials: true ve tam Origin ile sunucu, SameSite=None; Secure özelliklerine sahip çerez ve credentials: 'include' veya withCredentials: true etkinleştirilmiş istemci. Bu üç noktaya uyarak sorun tamamen çözülecektir.


Güvenilir Altyapı, Geliştiriciler İçin İç Huzuru

CORS'un doğru uygulanması ve çerez yönetimi hikayenin sadece bir parçası; projenizin üzerinde çalıştığı altyapı da hizmetin kararlılığı ve güvenliğinde belirleyici bir rol oynar:

Radib Hosting — Ücretsiz SSL ve standart başlık yapılandırması ile tam destekli yüksek hızlı web barındırma; projelerinizin ön yüz ve arka yüzünü barındırmak için ideal bir seçim.

Radib Virtual Server — Projeniz tam erişim, özel kaynaklar ve web sunucusu yapılandırmasında (Nginx/Apache) özgürlük gerektiriyorsa, güçlü donanım ve kararlı ağ ile Radib sanal sunucuları profesyonel API'ler için en iyi seçimdir.

Radib Debugging and Security Services — Karmaşık CORS hataları, kimlik doğrulama sorunları veya güvenlik zorlukları ile uğraşıyorsanız, web uygulamalarını sorun giderme ve güvenlik konusunda derin deneyime sahip Radib teknik ekibi, sorunu kökten çözmenize yardımcı olmak için yanınızdadır.

 

Bu cevap yeterince yardımcı oldu mu? 112 Bu dökümanı faydalı bulan kullanıcılar: (112 Oy)