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

Anda sedang melihat dokumentasi Apigee dan Apigee Hybrid.
Lihat dokumentasi Apigee Edge.

Header HTTP adalah pasangan nilai nama yang memungkinkan aplikasi klien dan layanan backend meneruskan informasi tambahan tentang permintaan dan respons. Beberapa contoh sederhana 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. Header multinilai akan memiliki nilai yang dipisahkan koma. Berikut 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 memungkinkan developer mengakses header dengan mudah menggunakan variabel alur dalam kebijakan atau alur bersyarat apa pun. Berikut daftar variabel yang dapat digunakan untuk mengakses header permintaan atau respons tertentu di Apigee:

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 AssignMessage 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>

Antipola

Mengakses nilai header HTTP dalam kebijakan Apigee dengan cara yang hanya menampilkan nilai pertama tidak benar dan dapat menyebabkan masalah jika header HTTP tertentu memiliki lebih dari satu nilai.

Bagian berikut berisi contoh akses header.

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

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

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 AssignMessage atau RaiseFault

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

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

Berikut bagian kode dari kebijakan AssignMessage atau RaiseFault yang menetapkan 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 hanya dengan nilai pertama dari header permintaan Access-Control-Allow-Headers, dalam contoh ini content-type.

Dampak

  1. Dalam kedua contoh di atas, perhatikan bahwa hanya nilai pertama dari header bernilai ganda yang ditampilkan. Jika nilai ini selanjutnya digunakan oleh kebijakan lain dalam alur Proxy API atau oleh layanan backend untuk melakukan beberapa fungsi atau logika, maka hal ini dapat menyebabkan hasil atau hasil yang tidak terduga.
  2. Saat nilai header permintaan diakses dan diteruskan ke server target, permintaan API dapat diproses secara salah oleh backend sehingga memberikan hasil yang salah.
  3. Jika aplikasi klien bergantung pada nilai header tertentu dari respons Apigee, maka aplikasi tersebut juga dapat diproses secara tidak benar dan memberikan hasil yang salah.

Praktik Terbaik

  1. Referensi request.header.header_name.values.string bentuk variabel alur untuk membaca semua nilai header tertentu.

    Contoh: Contoh fragmen yang dapat digunakan di RaiseFault atau AssignMessage untuk membaca header multi-nilai

    <Set>
      <Headers>
        <Header name="Inbound-Headers">{request.header.Accept.values.string}</Header>
      </Headers>
    </Set>
  2. Jika ingin akses individual ke setiap nilai berbeda, Anda dapat menggunakan 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 JavaScript atau JavaCallout.

    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 dua nilai dengan kode di atas. Nilai pertama adalah application/xml;q=0.9, dan yang kedua adalah */*;q=0.8 .

    Jika nilai header perlu dipisahkan menggunakan titik koma sebagai pembatas, Anda dapat menggunakan string.split(";") dalam panggilan JavaScript untuk memisahkan nilai yang berbeda.

  3. Sebagai alternatif, Anda dapat menggunakan fungsi substring() yang tersedia dalam template pesan pada variabel alur request.header.header_name.values untuk membaca semua nilai header tertentu.

    Contoh: Menggunakan substring() dalam template pesan untuk membaca header multi-nilai lengkap

    <Set>
      <Headers>
       <Header name="Inbound-Headers">{substring(request.header.Accept.values,1,-1)}</Header>
      </Headers>
    </Set>

Bacaan lebih lanjut