AMP'de CORS
Birçok AMP bileşeni ve uzantısı, kökler arası kaynak paylaşımı (CORS) isteklerini kullanarak uzak uç noktalardan yararlanır. Bu belge, AMP'de CORS kullanmanın temel yönlerini açıklamaktadır. CORS hakkında bilgi edinmek için bkz: W3 CORS Teknik Özellikleri.
Kaynağım için neden CORS'a ihtiyacım var?
Kendi kaynağınıza yönelik talepler için neden CORS'a ihtiyacınız olduğu konusunda kafanız karışabilir, hadi konuyu inceleyelim.
Dinamik verilerini (ör. amp-form, amp-list vb.) alan AMP bileşenleri, verileri almak için uzak uç noktalara CORS isteklerinde bulunur. AMP sayfanız bu tür bileşenler içeriyorsa, bu isteklerin başarısız olmaması için CORS'u işlemeniz gerekir.
Bunu bir örnekle gösterelim:
Fiyatları olan ürünleri listeleyen bir AMP sayfanız olduğunu varsayalım. Sayfadaki fiyatları güncellemek için, kullanıcı bir json uç noktasından en son fiyatları alan bir düğmeye tıklar (amp-list bileşeni aracılığıyla yapılır). JSON sizin etki alanınızda.
Tamam, yani sayfa etki alanımda ve JSON'da etki alanımda. Ben bir sorun göremiyorum!
Peki, ama kullanıcınız AMP sayfanıza nasıl ulaştı? Eriştikleri önbelleğe alınmış bir sayfa mı? Kullanıcınız büyük olasılıkla AMP sayfanıza doğrudan erişmemiş, bunun yerine sayfanızı başka bir platform aracılığıyla keşfetmiştir. Örneğin, Google Araması, AMP sayfalarını hızlı bir şekilde oluşturmak için Google AMP önbelleğini kullanır; bunlar, farklı etki alanı olan Google AMP Önbelleğinden sunulan önbelleğe alınmış sayfalardır. Kullanıcınız sayfanızdaki fiyatları güncellemek için düğmeye tıkladığında, önbelleğe alınmış AMP sayfası, kaynaklar (önbellek -> kaynak etki alanı) arasında bir uyumsuzluk olan fiyatları almak için kaynak etki alanınıza bir istek gönderir. Bu tür çapraz kaynaklı isteklere izin vermek için CORS'u işlemeniz gerekir, aksi takdirde istek başarısız olur.
Peki, ne yapmalıyım?
- Dinamik veri getiren AMP sayfaları için, bu sayfaların önbelleğe alınmış sürümünü test ettiğinizden emin olun; sadece kendi etki alanınızda test etmeyin. (Aşağıdaki AMP'de CORS'u Test Etme bölümüne bakın)
- CORS isteklerini ve yanıtlarını işlemek için bu belgedeki yönergeleri izleyin.
CORS istekleri için çerezleri kullanma
CORS isteklerini kullanan çoğu AMP bileşeni, kimlik bilgileri modunu otomatik olarak ayarlar veya yazarın isteğe bağlı olarak etkinleştirmesine izin verir. Örneğin, amp-list
bileşeni, bir cors JSON uç noktasından dinamik içerik getirir ve yazarın credentials
özniteliği aracılığıyla kimlik bilgisi modunu ayarlamasına izin verir.
Örnek: Çerezler aracılığıyla bir amp-list öğesine kişiselleştirilmiş içerik eklemek
<amp-list credentials="include" src="<%host%>/json/product.json?clientId=CLIENT_ID(myCookieId)" > <template type="amp-mustache"> Your personal offer: ${{price}} </template> </amp-list>
Kimlik bilgileri modunu belirterek; kaynak, CORS isteğine çerezleri ekleyebilir ve ayrıca yanıtta çerezler ayarlayabilir (üçüncü taraf çerez kısıtlamalarına tabidir).
Üçüncü taraf çerez kısıtlamaları
Tarayıcıda belirtilen aynı üçüncü taraf çerez kısıtlamaları, AMP'deki credentialed CORS istekleri için de geçerlidir. Bu kısıtlamalar tarayıcıya ve platforma bağlıdır, ancak bazı tarayıcılar için kaynak, yalnızca kullanıcı daha önce kaynağı 1.taraf (üst) bir pencerede ziyaret ettiyse çerezleri ayarlayabilir. Veya başka bir deyişle, yalnızca kullanıcı kaynak web sitesini doğrudan ziyaret ettikten sonra. Bu göz önüne alındığında, CORS aracılığıyla erişilen bir hizmet, varsayılan olarak çerezleri ayarlayabileceğini varsayamaz.
AMP'de CORS güvenliği
AMP sayfalarınız için geçerli ve güvenli istek ve yanıtlar sağlamak için şunları yapmanız gerekir:
Arka uçta bir Node kullanıyorsanız, AMP Toolbox'ın bir parçası olan AMP CORS ara katman yazılımını kullanabilirsiniz.
CORS isteklerini doğrulama
Bitiş noktanız bir CORS isteği aldığında:
- CORS
Origin
başlığının izin verilen bir kaynak olduğunu doğrulayın (yayıncının kaynağı + AMP önbellekleri). - Bir Origin Başlığı yoksa, isteğin aynı kaynaktan (
AMP-Same-Origin
aracılığıyla) olup olmadığını kontrol edin.
1) Belirli CORS kaynakları için isteklere izin verme
CORS uç noktaları, Origin
HTTP üstbilgisi aracılığıyla istekte bulunan kaynağı alır. Uç noktalar yalnızca aşağıdaki isteklere izin vermelidir: (1) yayıncının kendi kaynağı ve (2) https://cdn.ampproject.org/caches.json'da listelenen her cacheDomain
kaynağı.
Örneğin, uç noktalar isteklere izin vermelidir:
- Google AMP Önbelleği alt etki alanı:
https://<publisher's domain>.cdn.ampproject.org
(örneğin,https://nytimes-com.cdn.ampproject.org
)
2) same-origin isteklerine izin verme
Origin
başlığının eksik olduğu aynı kaynak istekleri için AMP aşağıdaki özel başlığı ayarlar:
AMP-Same-Origin: true
Bu özel başlık, aynı kaynaktan bir XHR isteği yapıldığında AMP Çalışma Zamanı tarafından gönderilir (yani, önbellek olmayan bir URL'den sunulan belge). AMP-Same-Origin:true
başlığını içeren isteklere izin verin.
CORS yanıt başlıklarını gönderme
CORS isteğini doğruladıktan sonra, ortaya çıkan HTTP yanıtı aşağıdaki üstbilgileri içermelidir:
Access-Control-Allow-Origin: <origin>
Bu başlık, bir W3 CORS Teknik Özellikleri gereksinimidir. Burada origin
, CORS Origin
istek başlığı aracılığıyla izin verilen talep kaynağı anlamına gelir. (Örneğin, "https://<publisher's subdomain>.cdn.ampproject.org"
).
W3 CORS teknik özellikleri, yanıtta *
değerinin döndürülmesine izin verse de, daha iyi güvenlik için şunları yapmalısınız:
Origin
başlığı varsa,Origin
başlığının değerini doğrulayın ve yineleyin.
Durum değiştirme isteklerini işleme
Sisteminizin durumunu değiştirebilecek istekleri işlemeden önce (Örneğin, bir kullanıcı bir posta listesine abone olur veya abonelikten çıkar), aşağıdakileri kontrol edin:
Origin
başlığı ayarlanmışsa:
- Kaynak aşağıdaki değerlerden biriyle eşleşmiyorsa, durdurun ve bir hata yanıtı döndürün:
<publisher's domain>.cdn.ampproject.org
- yayıncının kaynağı (yani sizinki)
burada *
gerçek bir yıldız işaretini ( * ) değil, bir joker karakter eşleşmesini temsil eder.
- Aksi takdirde, isteği işleyin.
Origin
bağlığı AYARLANMAMIŞSA:
- İsteğin
AMP-Same-Origin: true
başlığını içerdiğini doğrulayın. İstek bu başlığı içermiyorsa, durdurun ve bir hata yanıtı verin. - Aksi takdirde, isteği işleyin.
Örnek izlenecek yol: CORS isteklerini ve yanıtlarını işleme
Uç noktanıza CORS isteklerini hesaba katmak için iki senaryo vardır:
- Aynı kaynaktan gelen bir istek.
- Önbelleğe alınmış bir kaynaktan (AMP önbelleğinden) bir istek.
Bu senaryoları bir örnekle ele alalım. Örneğimizde, article-amp.html.
adlı bir AMP sayfasını barındıran example.com
sitesini yönetiyoruz. AMP sayfası, yine example.com
'da barındırılan bir data.json
dosyasından dinamik verileri almak için bir aamp-list
içeriyor. AMP sayfamızdan gelen data.json
dosyamıza gelen istekleri işlemek istiyoruz. Bu istekler, aynı kaynaktaki (önbelleğe alınmamış) AMP sayfasından veya farklı bir kaynaktaki (önbelleğe alınmış) AMP sayfasından olabilir.
İzin verilen kaynaklar
CORS ve AMP hakkında bildiklerimize dayanarak (yukarıdaki CORS isteklerini doğrulamak), örneğimiz için aşağıdaki etki alanlarından gelen isteklere izin vereceğiz:
example.com
--- Yayıncının etki alanıexample-com.cdn.ampproject.org
--- Google AMP Önbelleği alt etki alanı
İzin verilen istekler için yanıt başlıkları
İzin verilen kaynaklardan gelen istekler için yanıtımız aşağıdaki başlıkları içerecektir:
Access-Control-Allow-Origin: <origin>
Bunlar, CORS yanıtımıza dahil edebileceğimiz ek yanıt başlıklarıdır:
Access-Control-Allow-Credentials: true Content-Type: application/json Access-Control-Max-Age: <delta-seconds> Cache-Control: private, no-cache
Sözde CORS mantığı
CORS isteklerini ve yanıtlarını işleme mantığımız aşağıdaki sözde kodda basitleştirilebilir:
IF CORS header present IF origin IN allowed-origins allow request & send response ELSE deny request ELSE IF "AMP-Same-Origin: true" allow request & send response ELSE deny request
CORS örnek kodu
CORS isteklerini ve yanıtlarını işlemek için kullanabileceğimiz örnek bir JavaScript işlevi:
function assertCors(req, res, opt_validMethods, opt_exposeHeaders) { var unauthorized = 'Unauthorized Request'; var origin; var allowedOrigins = [ 'https://example.com', 'https://example-com.cdn.ampproject.org', 'https://cdn.ampproject.org', ]; var allowedSourceOrigin = 'https://example.com'; //publisher's origin // If same origin if (req.headers['amp-same-origin'] == 'true') { origin = sourceOrigin; // If allowed CORS origin & allowed source origin } else if ( allowedOrigins.indexOf(req.headers.origin) != -1 && sourceOrigin == allowedSourceOrigin ) { origin = req.headers.origin; } else { res.statusCode = 403; res.end(JSON.stringify({message: unauthorized})); throw unauthorized; } res.setHeader('Access-Control-Allow-Credentials', 'true'); res.setHeader('Access-Control-Allow-Origin', origin); }
Not: Çalışan bir kod örneği için bkz. amp-cors.js.
Senaryo 1: Aynı kaynaktaki AMP sayfasından istek alma
Aşağıdaki senaryoda, article-amp.html
sayfası data.json
dosyasını ister; kaynaklar aynıdır.
İsteği incelersek şunları bulacağız:
Request URL: https://example.com/data.json Request Method: GET AMP-Same-Origin: true
Bu istek aynı kaynaktan geldiğinden, Origin
başlığı yoktur, ancak AMP-Same-Origin: true
özel AMP istek başlığı mevcuttur. Aynı kaynaktan olduğu için bu talebe izin verebiliriz (https://example.com
).
Yanıt başlıklarımız şöyle olacaktır:
Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://example.com
Senaryo 2: Önbelleğe alınmış AMP sayfasından istek alma
Aşağıdaki senaryoda, Google AMP Önbelleğinde önbelleğe alınan article-amp.html
sayfası data.json
dosyasını ister; kaynaklar farklıdır.
İsteği incelersek şunları bulacağız:
Request URL: https://example.com/data.json Request Method: GET Origin: https://example-com.cdn.ampproject.org
Bu istek bir Origin
başlığı içerdiğinden, izin verilen bir kaynaktan olduğunu doğrularız. İzin verilen bir kaynaktan olduğu için bu isteğe izin verebiliriz.
Yanıt başlıklarımız şöyle olacaktır:
Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://example-com.cdn.ampproject.org
Önbelleğe alınmış yazı tipleri ile çalışma
Google AMP Önbelleği, AMP sayfasının hızını optimize etmek için AMP HTML belgelerini, resimlerini ve yazı tiplerini önbelleğe alır. AMP sayfasını hızlı hale getirirken, önbelleğe alınmış kaynakların güvenliğini sağlamada da dikkatli olmak istiyoruz. AMP önbelleğinin kaynağının Access-Control-Allow-Origin
değerine dikkat ederek, genellikle yazı tipleri için önbelleğe alınmış kaynaklara nasıl yanıt verdiğine dair bir değişiklik yapacağız.
Geçmiş davranış (Ekim 2019'dan önce)
Bir AMP sayfası @font-face src
özniteliğinden https://example.com/some/font.ttf
yüklerken, AMP Önbelleği yazı tipi dosyasını önbelleğe alacak ve aşağıdaki gibi joker karakter Access-Control-Allow-Origin
'e sahip olarak kaynağı sunacaktır.
- URL
https://example-com.cdn.ampproject.org/r/s/example.com/some/font.tff
- Access-Control-Allow-Origin: *
Yeni davranış (Ekim 2019 ve sonrası)
Mevcut uygulama izin verici olsa da, bu, çapraz kaynak sitelerden yazı tiplerinin beklenmedik şekilde kullanılmasına yol açabilir. Bu değişiklikte AMP Önbelleği, kaynak sunucunun yanıt verdiği aynı Access-Control-Allow-Origin
değeriyle yanıt vermeye başlayacaktır. Yazı tiplerini önbelleğe alınmış AMP belgesinden düzgün şekilde yüklemek için, AMP Önbelleği kaynağını başlık aracılığıyla kabul etmeniz gerekir.
Örnek bir uygulama şöyle olacaktır:
function assertFontCors(req, res, opt_validMethods, opt_exposeHeaders) { var unauthorized = 'Unauthorized Request'; var allowedOrigins = [ 'https://example.com', 'https://example-com.cdn.ampproject.org', ]; // If allowed CORS origin if (allowedOrigins.indexOf(req.headers.origin) != -1) { res.setHeader('Access-Control-Allow-Origin', req.headers.origin); } else { res.statusCode = 403; res.end(JSON.stringify({message: unauthorized})); throw unauthorized; } }
Örnek olarak, https://example.com/amp.html
'de /some/font.ttf dosyasını yüklemek isterseniz, kaynak sunucu aşağıdaki gibi Access-Control-Allow-Origin başlığıyla yanıt vermelidir.
Access-Control-Allow-Origin
ile yanıt verebilirsiniz, AMP Önbelleği de bu değeri yansıtacaktır. Yani bu, Access-Control-Allow-Origin: *
ile yanıt vereceği anlamına gelir. Zaten bu ayara sahipseniz, hiçbir şeyi değiştirmeye gerek yoktur. Bu değişikliği Ekim 2019 ortalarında yapmayı planlıyoruz ve kendi kendine barındırılan yazı tiplerini kullanan her AMP yayıncısının etkilenip etkilenmediğini kontrol etmesini bekliyoruz.
Yayın planı
- 30-09-2019: Sürüm, bu değişikliğin hangi etki alanları için geçerli olduğu konusunda daha kesin denetim içerir. Bu derleme, bu hafta içinde kullanıma sunulacaktır.
- 07/10/2019: Manuel test için test alanları etkinleştirilecektir.
- 14/10/2019: Özellik genel olarak kullanıma sunulacaktır. (Ancak testin nasıl gittiğine bağlı olarak).
İlgili sorununu buradan takip edin.
AMP'de CORS'u test etme
AMP sayfalarınızı test ederken, AMP sayfalarınızın önbelleğe alınmış sürümlerinden testler eklediğinizden emin olun.
Sayfayı önbellek URL'si ile doğrulayın
Önbelleğe alınmış AMP sayfanızın doğru şekilde oluşturulduğundan ve çalıştığından emin olmak için:
- Tarayıcınızdan, AMP Önbelleğinin AMP sayfanıza erişmek için kullanacağı URL'yi açın. Önbellek URL biçimini bu araçtan Örneklerle AMP'den belirleyebilirsiniz.
Örneğin:
- URL:
https://amp.dev/documentation/guides-and-tutorials/start/create/
- AMP Önbelleği URL biçimi:
https://www-ampproject-org.cdn.ampproject.org/c/s/www.ampproject.org/docs/tutorials/create.html
- Tarayıcınızın geliştirme araçlarını açın; hata olmadığını ve tüm kaynakların doğru yüklendiğini doğrulayın.
Sunucu yanıtı başlıklarınızı doğrulayın
Sunucunuzun doğru HTTP yanıt başlıklarını gönderdiğini doğrulamak için curl
komutunu kullanabilirsiniz. curl
komutunda, istek URL'sini ve eklemek istediğiniz özel başlıkları belirtin.
Sözdizimi: curl <request-url> -H <custom-header> - I
Aynı kaynaktan test isteği
Aynı kaynaklı bir istekte, AMP sistemi özel AMP-Same-Origin:true
başlığını ekler.
İşte https://ampbyexample.com
'dan examples.json
dosyasına (aynı etki alanında) bir isteği test etmek için curl komutumuz:
curl 'https://amp.dev/static/samples/json/examples.json' -H 'AMP-Same-Origin: true' -I
Komuttan elde edilen sonuçlar doğru yanıt başlıklarını gösterir (not: fazla bilgiler kırpılmıştır):
HTTP/2 200 access-control-allow-headers: Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token access-control-allow-credentials: true access-control-allow-origin: https://ampbyexample.com access-control-allow-methods: POST, GET, OPTIONS
Önbelleğe alınmış AMP sayfasından test isteği
Aynı etki alanından (yani önbellek) olmayan bir CORS isteğinde, origin
başlığı isteğin bir parçasıdır.
Google AMP Önbelleğinde önbelleğe alınmış AMP sayfasından examples.json{/code0 dosyasına bir isteği test etmek için curl komutumuz şu şekildedir:
curl 'https://amp.dev/static/samples/json/examples.json' -H 'origin: https://ampbyexample-com.cdn.ampproject.org' -I
Komuttan elde edilen sonuçlar doğru yanıt başlıklarını gösterir:
HTTP/2 200
access-control-allow-headers: Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token
access-control-allow-credentials: true
access-control-allow-origin: https://ampbyexample-com.cdn.ampproject.org
access-control-allow-methods: POST, GET, OPTIONS