Antipola: Mengakses header HTTP multi-nilai dengan tidak benar di Proxy API

Anda sedang melihat dokumentasi Apigee Edge.
Buka Dokumentasi Apigee X.
info

Header HTTP adalah pasangan nilai nama yang mengizinkan aplikasi klien dan layanan backend untuk meneruskan informasi tambahan tentang permintaan dan respons. Beberapa contoh sederhananya adalah:

  • Header permintaan otorisasi meneruskan kredensial pengguna ke server:
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • Header Content-Type menunjukkan jenis konten permintaan/respons yang dikirim:
    Content-Type: application/json

Header HTTP dapat memiliki satu atau beberapa nilai bergantung pada definisi kolom header. {i>Header<i} multi-nilai akan memiliki nilai yang dipisahkan koma. Berikut adalah beberapa contoh header yang berisi beberapa nilai:

  • 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 memungkinkan developer mengakses header dengan mudah menggunakan variabel flow dalam kebijakan Edge atau alur kondisional. Berikut adalah daftar variabel yang dapat digunakan untuk mengakses header permintaan atau respons tertentu di Edge:

Variabel alur:

  • 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

Objek JavaScript:

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

Berikut adalah contoh kebijakan MenetapkanMessage yang menunjukkan cara membaca nilai header permintaan dan menyimpannya ke dalam variabel:

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

Anti-pola

Mengakses nilai header HTTP dalam kebijakan Edge dengan cara yang hanya menampilkan nilai pertama salah dan dapat menyebabkan masalah jika Header HTTP tertentu memiliki lebih dari satu nilai.

Bagian berikut berisi contoh akses {i>header<i}.

Contoh 1: Membaca header Accept multi-nilai menggunakan kode JavaScript

Perhatikan bahwa header Accept memiliki beberapa nilai seperti yang ditunjukkan di bawah ini:

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

Berikut adalah kode JavaScript yang membaca nilai dari header Accept:

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

Kode JavaScript di atas hanya menampilkan nilai pertama dari header Accept, seperti text/html.

Contoh 2: Membaca header Access-Control-Allow-Headers multi-nilai dalam kebijakan PrepareMessage atau RaiseFault

Perhatikan bahwa header Access-Control-Allow-Headers memiliki beberapa nilai seperti yang ditunjukkan di bawah ini:

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

Berikut adalah bagian kode dari kebijakan MenetapkanMessage atau RaiseFault yang menyetel header Access-Control-Allow-Headers:

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

Kode di atas menetapkan Header Access-Control-Allow-Headers dengan hanya nilai pertama dari header permintaan Access-Control-Allow-Headers, dalam contoh ini content-type.

Dampak

  1. Pada kedua contoh di atas, perhatikan bahwa hanya nilai pertama dari header multinilai yang ditampilkan. Jika nilai ini selanjutnya digunakan oleh kebijakan lain dalam alur Proxy API atau oleh layanan backend menjalankan fungsi atau logika tertentu, maka hal itu dapat mengarah pada suatu hasil atau hasil yang tidak diharapkan.
  2. Saat nilai header permintaan diakses dan diteruskan ke server target, permintaan API dapat tidak diproses oleh backend dengan benar dan karenanya mungkin memberikan hasil yang salah.
  3. Jika aplikasi klien bergantung pada nilai header tertentu dari respons Edge, maka aplikasi juga dapat memproses dengan tidak benar dan memberikan hasil yang salah.

Praktik Terbaik

  1. Gunakan variabel alur bawaan yang sesuai: request.header.header_name.values.count, request.header.header_name.N, response.header.header_name.values.count, response.header.header_name.N.

    Kemudian, lakukan iterasi untuk mengambil semua nilai dari header tertentu dalam kebijakan pemanggilan JavaScript atau Java.

    Contoh: Contoh kode JavaScript untuk membaca header multi-nilai

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

    Misalnya, application/xml;q=0.9, */*;q=0.8 akan muncul sebagai satu nilai dengan kode di atas.

    Jika nilai header perlu dipisahkan menggunakan titik koma sebagai pembatas, gunakan string.split(";") untuk memisahkannya menjadi nilai.

  2. Gunakan fungsi substring() pada variabel flow request.header.header_name.values dalam kebijakan RaiseFault atau Menetapkan Pesan untuk membaca semua nilai header tertentu.

    Contoh: Contoh RaiseFault atau Menetapkan Pesan untuk membaca header multi-nilai

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

Bacaan lebih lanjut