Phản mẫu: Truy cập không chính xác các tiêu đề HTTP nhiều giá trị trong Proxy API

Bạn đang xem tài liệu về Apigee Edge.
Truy cập vào tài liệu Apigee X.
thông tin

Tiêu đề HTTP là các cặp giá trị tên cho phép các ứng dụng khách và dịch vụ phụ trợ truyền thêm thông tin về các yêu cầu và phản hồi tương ứng. Sau đây là một số ví dụ đơn giản:

  • Tiêu đề của yêu cầu uỷ quyền chuyển thông tin đăng nhập của người dùng đến máy chủ:
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • Tiêu đề Content-Type cho biết loại nội dung yêu cầu/phản hồi đang được gửi:
    Content-Type: application/json

Tiêu đề HTTP có thể có một hoặc nhiều giá trị tuỳ thuộc vào định nghĩa trường tiêu đề. Tiêu đề có nhiều giá trị sẽ có các giá trị được phân tách bằng dấu phẩy. Sau đây là một số ví dụ về tiêu đề chứa nhiều giá trị:

  • 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 cho phép nhà phát triển dễ dàng truy cập vào các tiêu đề bằng cách sử dụng biến luồng trong bất kỳ chính sách hoặc luồng có điều kiện nào của Edge. Sau đây là danh sách các biến có thể dùng để truy cập vào một tiêu đề yêu cầu hoặc tiêu đề phản hồi cụ thể trong Edge:

Biến luồng:

  • 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

Đối tượng JavaScript:

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

Sau đây là chính sách AssignMessage mẫu cho biết cách đọc giá trị của tiêu đề yêu cầu và lưu trữ giá trị đó vào một biến:

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

Antipattern

Việc truy cập vào các giá trị của tiêu đề HTTP trong các chính sách của Edge theo cách chỉ trả về giá trị đầu tiên là không chính xác và có thể gây ra vấn đề nếu(các) tiêu đề HTTP cụ thể có nhiều giá trị.

Các phần sau đây chứa ví dụ về quyền truy cập vào tiêu đề.

Ví dụ 1: Đọc tiêu đề Accept có nhiều giá trị bằng mã JavaScript

Giả sử tiêu đề Accept có nhiều giá trị như minh hoạ bên dưới:

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

Sau đây là mã JavaScript đọc giá trị từ tiêu đề Accept:

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

Đoạn mã JavaScript ở trên chỉ trả về giá trị đầu tiên từ tiêu đề Accept, chẳng hạn như text/html.

Ví dụ 2: Đọc tiêu đề Access-Control-Allow-Headers có nhiều giá trị trong chính sách AssignMessage hoặc RaiseFault

Giả sử tiêu đề Access-Control-Allow-Headers có nhiều giá trị như minh hoạ bên dưới:

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

Sau đây là phần mã từ chế độ cài đặt chính sách AssignMessage hoặc RaiseFault đặt tiêu đề Access-Control-Allow-Headers:

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

Đoạn mã trên đặt Tiêu đề Access-Control-Allow-Headers chỉ với giá trị đầu tiên từ tiêu đề của yêu cầu Access-Control-Allow-Headers, trong ví dụ này là content-type.

Tác động

  1. Trong cả hai ví dụ trên, hãy lưu ý rằng chỉ giá trị đầu tiên trong các tiêu đề có nhiều giá trị được trả về. Nếu các giá trị này sau đó được một chính sách khác sử dụng trong luồng API Proxy hoặc do dịch vụ phụ trợ sử dụng để thực hiện một số chức năng hoặc logic, thì điều này có thể dẫn đến kết quả hoặc kết quả không mong muốn.
  2. Khi các giá trị tiêu đề của yêu cầu được truy cập và truyền đến máy chủ đích, các yêu cầu API có thể được xử lý không chính xác bởi phần phụ trợ và do đó, các yêu cầu này có thể đưa ra kết quả không chính xác.
  3. Nếu ứng dụng khách phụ thuộc vào các giá trị tiêu đề cụ thể trong phản hồi Edge, thì ứng dụng đó cũng có thể xử lý không chính xác và đưa ra kết quả không chính xác.

Phương pháp hay nhất

  1. Sử dụng các biến luồng tích hợp thích hợp: request.header.header_name.values.count, request.header.header_name.N, response.header.header_name.values.count, response.header.header_name.N.

    Sau đó, lặp lại để tìm nạp tất cả các giá trị từ một tiêu đề cụ thể trong các chính sách chú thích JavaScript hoặc Java.

    Ví dụ: Đoạn mã JavaScript mẫu để đọc tiêu đề có nhiều giá trị

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

    Ví dụ: application/xml;q=0.9, */*;q=0.8 sẽ xuất hiện dưới dạng một giá trị với mã ở trên.

    Nếu bạn cần phân tách các giá trị tiêu đề bằng dấu chấm phẩy làm dấu phân cách, hãy dùng string.split(";") để phân tách các giá trị này.

  2. Sử dụng hàm substring() trên biến luồng request.header.header_name.values trong chính sách RaiseFault hoặc AssignMessage để đọc tất cả các giá trị của một tiêu đề cụ thể.

    Ví dụ: Chính sách RaiseFault hoặc AssignMessage mẫu để đọc tiêu đề có nhiều giá trị

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

Tài liệu đọc thêm