API proxy'sine CORS desteği ekleme

Apigee Edge belgelerini görüntülüyorsunuz.
. Git: Apigee X belgeleri.
bilgi

CORS (Kaynaklar arası kaynak paylaşımı), JavaScript'in kullanılmasına izin veren standart bir mekanizmadır Kaynak olmayan kaynaklardan gelen kaynaklarla etkileşim kurmak için bir web sayfasında yürütülen XMLHttpRequest (XHR) çağrıları alanlar. CORS, "aynı kaynak politikasına" yönelik yaygın olarak uygulanan bir çözümdür tarafından zorunlu kılınan tüm tarayıcılarda kullanılabilir. Örneğin, JavaScript kodundan Twitter API'ye XHR çağrısı yaparsanız çağrı başarısız olur. Bunun nedeni, sayfayı tarayıcınız, Twitter API'sini sunan alan adıyla aynı değildir. CORS, genel olarak bu soruna sunucu tarafından “kaydolma” özelliğini kökler arası kaynak sağlamak istiyorlar. paylaşım.

Video: API proxy'sinde CORS'yi nasıl etkinleştireceğinizi öğrenmek için kısa bir video izleyin.

CORS için tipik kullanım alanı

Aşağıdaki JQuery kodu, hayali bir hedef hizmeti çağırır. bağlamına (bir web sayfası) aitse çağrı, aynı kaynak politikası nedeniyle başarısız olur:

<script>
var url = "http://service.example.com";
$(document).ready(function(){
  $("button").click(function(){
    $.ajax({
        type:"GET",
        url:url,
        async:true,
        dataType: "json",
           success: function(json) {
              // Parse the response.
              // Do other things.
           },
           error: function(xhr, status, err) {
              // This is where we end up!
            }
    });
  });
});
</script>

Bu sorunun çözümlerinden biri, arka uçta oluşturur. Edge'in istemci (bu durumda tarayıcı) ile arka uç arasında bulunduğunu unutmayın API (hizmet). API proxy'si tarayıcıda değil, sunucuda yürütüldüğü için is, hizmeti başarılı bir şekilde çağırabilir. Sonrasında tek yapmanız gereken TargetEndpoint yanıtına CORS başlıkları eklemek. Tarayıcı CORS'yi desteklediği sürece bu başlıklar, tarayıcıya "rahatlamanın" bir sorun olmadığını izin verir. Böylece, kaynaklar arası API çağrısının başarılı olması için.

CORS destekli proxy oluşturulduktan sonra arka uç hizmetini kullanabilirsiniz. Örneğin:

<script>
var url = "http://myorg-test.apigee.net/v1/example";
$(document).ready(function(){
  $("button").click(function(){
    $.ajax({
        type:"GET",
        url:url,
        async:true,
        dataType: "json",
           success: function(json) {
              // Parse the response.
              // Do other things.
           },
           error: function(xhr, status, err) {
              // This time, we do not end up here!
            }
    });
  });
});
</script>

Yeni bir API'ye CORS ekleme politikası ekleme proxy

"CORS Ekle" düğmesi ekleyerek API proxy'sine CORS desteği ekleyebilirsiniz. API proxy'sine politika ekleyebilirsiniz. Bu politikayı eklemek için CORS başlıkları ekle onay kutusunu işaretleyin: Proxy Oluşturma sihirbazının Güvenlik sayfası.

Bu onay kutusunu işaretlediğinizde sisteme otomatik olarak CORS ekle adlı bir politika eklenir. ve aşağıdaki şekilde gösterildiği gibi TargetEndpoint yanıt ön akışına eklenir:

Politikalar bölümünün altındaki gezinme çubuğuna eklenen ve sağ kaydırmadaki TargetEndpoint yanıt ön akışına eklenen CORS politikası ekleyin

CORS ekleme politikası, assignMessage politikası olarak uygulanır ve yanıta uygun başlıkları ekler. Temel olarak başlıklar, tarayıcının kaynaklarını hangi kaynaklarla paylaşacağını bilmesini sağlar. kabul edilir vb. Bu CORS başlıkları hakkında daha fazla bilgi için Kaynaklar Arası Kaynak Paylaşımı W3C Önerisi.

Politikayı aşağıdaki şekilde değiştirmeniz gerekir:

  • Aşağıdaki kod alıntısında gösterildiği gibi, content-type ve authorization üstbilgilerini (temel kimlik doğrulamasını veya OAuth2'yi desteklemek için gereklidir) Access-Control-Allow-Headers başlığına ekleyin.
  • OAuth2 kimlik doğrulaması için RFC ile uyumlu olmayan davranışı düzeltmek için bazı adımlar atmanız gerekebilir.
  • Aşağıdaki alıntıda gösterildiği gibi CORS başlıklarını ayarlamak için <Add> yerine <Set> kullanılması önerilir. <Add> kullanırken Access-Control-Allow-Origin üstbilgisi zaten mevcutsa aşağıdaki hatayı alırsınız:

    The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.

    Daha fazla bilgi için bkz. CORS Hatası : Başlık birden çok değer ("*, *") içeriyor ancak yalnızca bir tanesine izin veriliyor.

<AssignMessage async="false" continueOnError="false" enabled="true" name="add-cors">
    <DisplayName>Add CORS</DisplayName>
    <FaultRules/>
    <Properties/>
    <Set>
        <Headers>
            <Header name="Access-Control-Allow-Origin">{request.header.origin}</Header>
            <Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type, authorization</Header>
            <Header name="Access-Control-Max-Age">3628800</Header>
            <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
        </Headers>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

Mevcut bir proxy'ye CORS başlıkları ekleme

Manuel olarak yeni bir "Mesaj Ata" politikası oluşturmanız ve CORS ekleme kodunu kopyalamanız gerekir. politika kapsamına girersiniz. Ardından politikayı, API proxy'sinin TargetEndpoint değerini bulun. Başlık değerlerini gerektiği gibi değiştirebilirsiniz. Daha fazla Politika oluşturma ve ekleme hakkında daha fazla bilgi için Politika nedir? bölümüne bakın.

CORS'yi yönetme yayın öncesi istekleri

CORS ön kontrol, kontrollü bir sunucu olup olmadığını doğrulamak için bir sunucuya istek göndermeyi CORS'yi destekler. Genel kontrol öncesi yanıtlar, sunucunun CORS'yi kabul edeceği kaynakları içerir. CORS istekleri için desteklenen HTTP yöntemlerinin bir listesi, isteğe bağlı olarak kaynak isteğinin bir parçası olarak kullanıldığında, ön kontrol için maksimum yanıt süresi önbelleğe alınır ve diğerleri. Hizmet, CORS desteği belirtmiyorsa veya çapraz kaynak kabul etmek istemiyorsa kaynağından gelen istekleri karşılamak için tarayıcının kaynaklar arası politikası uygulanır ve Sunucuda barındırılan kaynaklarla etkileşim kurmak için istemciden yapılan tüm web alanları arası istekler başarısız olur.

CORS ön kontrol istekleri genellikle HTTP OPTIONS yöntemiyle yapılır. Bir sunucu CORS'un OPTIONS isteği aldığını desteklerse, istemciye bir dizi CORS başlığı döndürür. CORS desteği düzeyini belirtin. Bu el sıkışmanın sonucunda müşteri bunun ne olduğunu bilir kaynak olmayan alandan istekte bulunmasına izin verilir.

Ön kontrol hakkında daha fazla bilgi için Kaynaklar Arası Kaynak Paylaşımı W3C Önerisi bölümüne bakın. İçinde CORS ile ilgili başvurabileceğiniz çok sayıda blog ve makaleye de göz atabilirsiniz.

Apigee, kullanıma hazır bir CORS ön uç çözümü içermez ancak kullanıma hazır bir uygulanmasına izin vermeniz gerekir. Amaç, proxy'nin SEÇENEKLERİ değerlendirmesidir koşullu akışta izlemesi gerekir. Proxy, sunucuya uygun bir yanıtı gerekir.

Şimdi örnek bir akışa göz atalım ve ardından yayın öncesi isteği işleyen bölümleri tartışalım:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <Flows>
        <Flow name="OptionsPreFlight">
            <Request/>
            <Response>
                <Step>
                    <Name>add-cors</Name>
                </Step>
            </Response>
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
        </Flow>
    </Flows>

    <PreFlow name="PreFlow">
        <Request/>
        <Response/>

    </PreFlow>
    <HTTPProxyConnection>
        <BasePath>/v1/cnc</BasePath>
        <VirtualHost>default</VirtualHost>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="NoRoute">
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </RouteRule>
    <RouteRule name="default">
        <TargetEndpoint>default</TargetEndpoint>
   </RouteRule>
   <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
</ProxyEndpoint>

Bu ProxyEndpoint'in temel bölümleri şunlardır:

  • OPTIONS isteğine yönelik bir koşulla NULL hedefe bir RouteRule oluşturulur. Lütfen hedef uç noktası belirtilmedi. OPTIONS isteğinin alınması ve Kaynak ve Access-Control-Request-Method istek başlıkları boş değil, proxy hemen İstemciye verilen yanıttaki CORS başlıkları (gerçek varsayılan "arka uç" hedefini atlayarak). Akış koşulları ve RouteRule ile ilgili ayrıntılar için Akış değişkenleri olan koşullar bölümüne bakın.

    <RouteRule name="NoRoute">
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </RouteRule>
    
  • CORS'yi içeren CORS ekleme politikası ekleyen bir OptionPreFlight akışı oluşturulur başlıklarına, bir OPTIONS isteği alındığında akışa Access-Control-Request-Method istek başlıkları boş değil.

     <Flow name="OptionsPreFlight">
                <Request/>
                <Response>
                    <Step>
                        <Name>add-cors</Name>
                    </Step>
                </Response>
            <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
     </Flow>
    

Örnek CORS çözümünü kullanma

GitHub'da paylaşılan akış olarak uygulanmış örnek bir CORS çözümü bulabilirsiniz. Paylaşılan akış paketini ortamınıza aktarın ve akış kancalarını kullanarak veya doğrudan API proxy akışlarına ekleyin. Ayrıntılar için CORS-Shared-FLow README dosyası örnekle birlikte sağlanır.