Falscher Zugriff auf HTTP-Header mit mehreren Werten in einem API-Proxy

Sie lesen gerade die Dokumentation zu Apigee Edge.
Zur Dokumentation zu Apigee X.
info

Die HTTP-Header sind die Name/Wert-Paare, mit denen Client- und Back-End-Dienste zusätzliche Informationen zu Anfragen und Antworten weiterleiten können. Hier einige einfache Beispiele:

  • Der Anfrageheader der Autorisierung übergibt die Anmeldedaten an den Server:
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • Der Header Content-Type gibt den Typ des gesendeten Anfrage-/Antwortinhalts an:
    Content-Type: application/json

Die HTTP-Header können je nach den Headerfelddefinitionen einen oder mehrere Werte haben. Ein Header mit mehreren Werten enthält kommagetrennte Werte. Beispiele für Header mit mehreren Werten:

  • 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 ermöglicht Entwicklern, über Ablaufvariablen in beliebigen Edge-Richtlinien oder bedingten Abläufen auf Header zuzugreifen. Hier ist eine Liste der Variablen, die verwendet werden können für den Zugriff auf einen bestimmten Anfrage- oder Antwortheader in Edge:

Ablaufvariablen:

  • 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-Objekte:

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

Hier ist ein Beispiel für eine AssignMessage-Richtlinie, die zeigt, wie ein Wert eines Anfrageheaders gelesen und in einer Variablen gespeichert wird:

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

Anti-Pattern

Der Zugriff auf die Werte von HTTP-Headern in Edge-Richtlinien, sodass nur der erste Wert zurückgegeben wird , ist nicht korrekt und kann zu Problemen führen, wenn die jeweiligen HTTP-Header mehrere Werte enthalten.

Die folgenden Abschnitte enthalten Beispiele für den Headerzugriff.

Beispiel 1: Header mit mehreren Werten mit JavaScript-Code lesen

Beachten Sie, dass der Header Accept mehrere Werte hat, wie unten gezeigt:

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

Hier ist der JavaScript-Code, mit dem der Wert des Headers Accept gelesen wird:

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

Der obige JavaScript-Code gibt nur den ersten Wert aus dem Accept Header, z. B. text/html zurück.

Beispiel 2: Mehrwertiger Header "Access-Control-Allow-Headers" in der Richtlinie "AssignedMessage" oder "RaiseFault" lesen

Beachten Sie, dass der Header Access-Control-Allow-Headers mehrere Werte hat, wie unten gezeigt:

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

Folgendes ist ein Teil des Codes aus der Richtlinie "AssignMessage" oder "Raisefault" für die Einstellung des Headers Access-Control-Allow-Headers:

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

Der obige Code legt den Header Access-Control-Allow-Headers mit dem ersten Wert aus dem Anfrageheader Access-Control-Allow-Headers fest, in diesem Beispiel content-type.

Auswirkungen

  1. Beachten Sie in beiden Beispielen, dass nur der erste Wert von Headern mit mehreren Werten zurückgegeben wird. Wenn diese Werte anschließend von einer anderen Richtlinie im API-Proxy-Ablauf oder vom Back-End-Dienst zum Ausführen einer Funktion oder Logik verwendet werden, kann dies zu einem unerwarteten Ergebnis führen.
  2. Wenn auf die Anfrageheaderwerte zugegriffen wird und diese an den Zielserver gesendet werden, werden API-Anfragen möglicherweise vom Back-End falsch verarbeitet und können daher fehlerhafte Ergebnisse liefern.
  3. Wenn die Clientanwendung von bestimmten Headerwerten aus der Edge-Antwort abhängig ist, kann sie auch falsch verarbeitet werden und falsche Ergebnisse liefern.

Best Practice

  1. Verwenden Sie die entsprechenden integrierten Ablaufvariablen: request.header.header_name.values.count, request.header.header_name.N, response.header.header_name.values.count, response.header.header_name.N.

    Wiederholen Sie dann den Vorgang, um alle Werte aus einem bestimmten Header in JavaScript- oder Java-Callout-Richtlinien abzurufen.

    Beispiel: JavaScript-Code zum Lesen eines Headers mit mehreren Werten

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

    Beispiel: application/xml;q=0.9, */*;q=0.8 wird mit dem obigen Code als ein einziger Wert angezeigt.

    Wenn die Headerwerte durch Semikolons getrennt werden müssen, trennen Sie sie mit string.split(";") in Werte.

  2. Zum Lesen aller Werte eines bestimmten Headers verwenden Sie die Funktion substring() für die Ablaufvariable request.header.header_name.values in der RaiseFault- oder AssignMessage-Richtlinie.

    Beispiel: Beispiel für RaiseFault- oder AssignMessage-Richtlinie zum Lesen eines mehrwertigen Headers

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

Weitere Informationen