Merkezler Arası Kaynak Paylaşımı (CORS)

Mariko Kosaka

Yayınlanma tarihi: 5 Kasım 2018

Tarayıcının aynı kaynak politikası, farklı bir kaynaktan gelen kaynağın okunmasını engeller. Bu mekanizma, kötü amaçlı sitelerin diğer sitelerin verilerini okumasını engeller ancak meşru kullanımları da önler.

Modern web uygulamaları genellikle farklı bir kaynaktan kaynak almak ister. Örneğin, farklı bir alandan JSON verilerini almak veya başka bir sitedeki resimleri bir <canvas> öğesine yüklemek. Bunlar, herkesin okuyabileceği kamuya açık kaynaklar olabilir ancak aynı kaynak politikası bunların kullanımını engeller. Geliştiriciler geçmişte JSONP gibi geçici çözümler kullanıyordu.

Merkezler Arası Kaynak Paylaşımı (CORS) bu sorunu standart bir şekilde düzeltir. CORS'u etkinleştirmek, sunucunun tarayıcıya ek bir kaynak kullanabileceğini bildirmesine olanak tanır.

Web'de kaynak isteği nasıl çalışır?

İstemci isteği ve sunucu yanıtı gösterilmektedir.

Tarayıcı ve sunucu, Hypertext Aktarım Protokolü (HTTP) kullanarak ağ üzerinden veri alışverişi yapabilir. HTTP, bir kaynağı almak için hangi bilgilerin gerekli olduğu da dahil olmak üzere, istekte bulunan ve yanıt veren arasındaki iletişim kurallarını tanımlar.

HTTP üstbilgisi, istemci ile sunucu arasındaki mesaj alışverişini düzenler ve erişimi belirlemek için kullanılır. Hem tarayıcının isteği hem de sunucunun yanıt iletisi başlık ve gövde olarak ikiye ayrılır.

Mesajın türü veya kodlaması gibi mesajla ilgili bilgiler. Bir başlık, anahtar/değer çiftleri olarak ifade edilen çeşitli bilgiler içerebilir. İstek başlığı ve yanıt başlığı farklı bilgiler içeriyor.

Örnek istek başlığı

Accept: text/html
Cookie: Version=1

Bu başlık, "Yanıt olarak HTML almak istiyorum" demeye eşdeğerdir. İşte bende olan bir çerez."

Örnek yanıt başlığı

Content-Encoding: gzip
Cache-Control: no-store

Bu başlık, "Bu yanıttaki veriler gzip ile kodlanmıştır" ifadesine eşdeğerdir. Don't cache this." (Bunu önbelleğe almayın.)

Gövde

İletinin kendisi. Bu, düz metin, ikili resim, JSON, HTML veya diğer birçok biçimde olabilir.

CORS nasıl çalışır?

Aynı kaynak politikası, tarayıcıya kaynaklar arası istekleri engellemesini söyler. Farklı bir kaynaktan herkese açık bir kaynağa ihtiyacınız olduğunda, kaynağı sağlayan sunucu tarayıcıya, isteği gönderen kaynağın kendi kaynağına erişebileceğini bildirir. Tarayıcı bunu hatırlar ve söz konusu kaynak için merkezler arası kaynak paylaşımına izin verir.

1. adım: İstemci (tarayıcı) isteği

Tarayıcı, kaynaklar arası bir istekte bulunduğunda geçerli kaynak (şema, ana makine ve bağlantı noktası) ile bir Origin başlığı ekler.

2. adım: Sunucu yanıtı

Bir sunucu bu üstbilgiyi gördüğünde ve erişime izin vermek istediğinde, yanıta istekte bulunan kaynağı belirten bir Access-Control-Allow-Origin üstbilgisi (veya herhangi bir kaynağa izin vermek için *) ekler.

3. adım: Tarayıcı yanıtı alır

Tarayıcı, uygun bir Access-Control-Allow-Origin üstbilgisiyle bu yanıtı gördüğünde yanıt verilerini istemci sitesiyle paylaşır.

CORS ile kimlik bilgilerini paylaşma

Gizlilik nedeniyle, CORS genellikle anonim istekler için kullanılır. Bu isteklerde, talepte bulunan kişi tanımlanmaz. CORS kullanırken göndereni tanımlayabilen çerezler göndermek istiyorsanız isteğe ve yanıta ek başlıklar eklemeniz gerekir.

İstek

Aşağıdaki örnekte gösterildiği gibi getirme seçeneklerine credentials: 'include' ekleyin. Bu, istekle birlikte gönderilen çerezi içerir:

fetch('https://example.com', {
  mode: 'cors',
  credentials: 'include'
})

Yanıt

Access-Control-Allow-Origin, belirli bir kaynağa (* kullanılarak joker karakter kullanılmaz) ayarlanmalı ve Access-Control-Allow-Credentials, true olarak ayarlanmalıdır.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

Karmaşık HTTP çağrıları için ön kontrol istekleri

Bir web uygulaması karmaşık bir HTTP isteğinde bulunduğunda tarayıcı, istek zincirinin başına bir ön kontrol isteği ekler.

CORS spesifikasyonu, karmaşık isteği aşağıdaki gibi tanımlar:

  • GET, POST veya HEAD dışındaki yöntemleri kullanan bir istek.
  • Accept, Accept-Language veya Content-Language dışında başlıklar içeren bir istek.
  • application/x-www-form-urlencoded, multipart/form-data veya text/plain dışında bir Content-Type üst bilgisine sahip istek.

Tarayıcılar, gerekli tüm ön kontrol isteklerini otomatik olarak oluşturur ve gerçek istek mesajından önce gönderir. Yayın öncesi isteği, aşağıdaki örnekteki gibi bir OPTIONS isteğidir:

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

Sunucu tarafında, isteği alan uygulama, ön kontrol isteğini uygulamanın bu kaynaktan kabul ettiği yöntemler hakkındaki bilgilerle yanıtlar:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

Sunucu yanıtı, ön kontrol sonuçlarının önbelleğe alınacağı süreyi saniye cinsinden belirtmek için Access-Control-Max-Age üstbilgisini de içerebilir. Bu sayede istemci, ön kontrol isteğini tekrarlamasına gerek kalmadan birden fazla karmaşık istek gönderebilir.