Antipattern: API Proxy'sinde birden çok değerli HTTP üstbilgilerine yanlış şekilde erişme

Apigee Edge belgelerini görüntülüyorsunuz.
Apigee X belgelerine gidin.
bilgi

HTTP üstbilgileri, istemci uygulamalarının ve arka uç hizmetlerinin sırasıyla istekler ve yanıtlar hakkında ek bilgi iletmesine olanak tanıyan ad-değer çiftleridir. Basit örnekler:

  • Yetkilendirme isteği başlığı, kullanıcı kimlik bilgilerini sunucuya iletir:
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • Content-Type üstbilgisi, gönderilen istek/yanıt içeriğinin türünü belirtir:
    Content-Type: application/json

HTTP üstbilgileri, üstbilgi alanı tanımlarına bağlı olarak bir veya daha fazla değere sahip olabilir. Çok değerli bir başlıkta virgülle ayrılmış değerler bulunur. Birden fazla değer içeren başlıklara dair birkaç örnek:

  • Cache-Control: no-cache, no-store, must-revalidate
  • Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
  • X-Forwarded-For: 10.125.5.30, 10.125.9.125

Apigee Edge, geliştiricilerin Edge politikalarının veya koşullu akışların herhangi birinde akış değişkenlerini kullanarak başlıklara kolayca erişmesini sağlar. Edge'de belirli bir istek veya yanıt başlığına erişmek için kullanılabilecek değişkenlerin listesini aşağıda bulabilirsiniz:

Akış değişkenleri:

  • message.header.header-name
  • request.header.header-name
  • response.header.header-name
  • message.header.header-name.N
  • request.header.header-name.N
  • response.header.header-name.N

JavaScript nesneleri:

  • context.proxyRequest.headers.header-name
  • context.targetRequest.headers.header-name
  • context.proxyResponse.headers.header-name
  • context.targetResponse.headers.header-name

Aşağıda, bir istek başlığının değerinin nasıl okunup değişkende depolanacağını gösteren örnek bir AssignMessage politikası verilmiştir:

<AssignMessage continueOnError="false" enabled="true" name="assign-message-default">
  <AssignVariable>
    <Name>reqUserAgent</Name>
    <Ref>request.header.User-Agent</Ref>
  </AssignVariable>
</AssignMessage>

Antipattern

Edge politikalarında HTTP üstbilgilerinin değerlerine yalnızca ilk değeri döndürecek şekilde erişmek yanlıştır ve belirli HTTP üstbilgilerinde birden fazla değer varsa sorunlara neden olabilir.

Aşağıdaki bölümlerde başlık erişimi örnekleri verilmiştir.

1. örnek: JavaScript kodu kullanarak çok değerli bir Accept başlığını okuma

Accept üstbilgisinin aşağıda gösterildiği gibi birden fazla değeri olduğunu varsayalım:

Accept: text/html, application/xhtml+xml, application/xml

Accept üstbilgisindeki değeri okuyan JavaScript kodu aşağıda verilmiştir:

// Read the values from Accept header
var acceptHeaderValues = context.getVariable("request.header.Accept");

Yukarıdaki JavaScript kodu, Accept başlığındaki yalnızca ilk değeri (ör. text/html) döndürür.

2. örnek: AssignMessage veya RaiseFault politikasında çok değerli bir Access-Control-Allow-Headers üstbilgisini okuma

Access-Control-Allow-Headers üstbilgisinin aşağıda gösterildiği gibi birden fazla değeri olduğunu varsayalım:

Access-Control-Allow-Headers: content-type, authorization

AssignMessage veya RaiseFault politikasında Access-Control-Allow-Headers üstbilgisini ayarlayan kod bölümü aşağıda verilmiştir:

<Set>
  <Headers>
    <Header name="Access-Control-Allow-Headers">{request.header.Access-Control-Request-Headers}</Header>
  </Headers>
</Set>

Yukarıdaki kod, başlığı Access-Control-Allow-Headers yalnızca istek başlığındaki Access-Control-Allow-Headers ilk değerle (bu örnekte content-type) ayarlar.

Etki

  1. Yukarıdaki her iki örnekte de çok değerli başlıklardan yalnızca ilk değerin döndürüldüğünü unutmayın. Bu değerler daha sonra API proxy'si akışındaki başka bir politika veya arka uç hizmeti tarafından bir işlev ya da mantık yürütmek için kullanılırsa beklenmedik bir sonuç ortaya çıkabilir.
  2. İstek başlığı değerlerine erişilip hedef sunucuya iletildiğinde API istekleri arka uç tarafından yanlış işlenebilir ve bu nedenle yanlış sonuçlar verebilir.
  3. İstemci uygulaması, Edge yanıtındaki belirli başlık değerlerine bağlıysa yanlış işleyebilir ve yanlış sonuçlar verebilir.

En İyi Uygulama

  1. Uygun yerleşik akış değişkenlerini kullanın: request.header.header_name.values.count, request.header.header_name.N, response.header.header_name.values.count, response.header.header_name.N.

    Ardından, JavaScript veya Java çağrı politikalarındaki belirli bir başlıktan tüm değerleri getirmek için yineleme yapın.

    Örnek: Çok değerli bir başlığı okumak için örnek JavaScript kodu

    for (var i = 1; i <=context.getVariable('request.header.Accept.values.count'); i++)
    {
      print(context.getVariable('request.header.Accept.' + i));
    }

    Örneğin, yukarıdaki kodla application/xml;q=0.9, */*;q=0.8 tek bir değer olarak görünür.

    Başlık değerlerinin noktalı virgül kullanılarak ayrılması gerekiyorsa bunları değerlere ayırmak için string.split(";") kullanın.

  2. Belirli bir üstbilginin tüm değerlerini okumak için RaiseFault veya AssignMessage politikasında akış değişkeni request.header.header_name.values üzerinde substring() işlevini kullanın.

    Örnek: Çok değerli bir başlığı okumak için örnek RaiseFault veya AssignMessage politikası

    <Set>
      <Headers>
       <Header name="Access-Control-Allow-Headers">{substring(request.header.Access-Control-Request-Headers.values,1,-1)}</Header>
      </Headers>
    </Set>

Daha fazla bilgi