안티패턴: API 프록시에서 다중 값 HTTP 헤더에 잘못된 액세스

현재 Apigee Edge 문서가 표시되고 있습니다.
Apigee X 문서로 이동
정보

HTTP 헤더는 클라이언트 애플리케이션과 백엔드 서비스가 각각 요청 및 응답에 대한 추가 정보를 전달할 수 있도록 하는 이름 값 쌍입니다. 다음은 몇 가지 간단한 예시입니다.

  • 승인 요청 헤더는 사용자 인증 정보를 서버에 전달합니다.
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • Content-Type 헤더는 전송 중인 요청/응답 콘텐츠의 유형을 나타냅니다.
    Content-Type: application/json

HTTP 헤더에는 헤더 필드 정의에 따라 하나 이상의 값이 있을 수 있습니다. 값이 여러 개인 헤더는 쉼표로 구분된 값을 갖습니다. 다음은 여러 값을 포함하는 헤더의 몇 가지 예시입니다.

  • 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를 사용하면 개발자가 모든 Edge 정책 또는 조건부 흐름에서 흐름 변수를 사용하여 헤더에 쉽게 액세스할 수 있습니다. 다음은 Edge에서 특정 요청 또는 응답 헤더에 액세스하는 데 사용할 수 있는 변수 목록입니다.

흐름 변수:

  • 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

자바스크립트 객체:

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

다음은 요청 헤더의 값을 읽고 변수에 저장하는 방법을 보여주는 샘플AssignMessage 정책입니다.

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

안티패턴

첫 번째 값만 반환하는 방식으로 에지 정책의 HTTP 헤더 값에 액세스하는 것은 올바르지 않으며 특정 HTTP 헤더에 값이 2개 이상 있는 경우 문제가 발생할 수 있습니다.

다음 섹션에는 헤더 액세스의 예시가 포함되어 있습니다.

예시 1: 자바스크립트 코드를 사용하여 다중 값 Accept 헤더 읽기

Accept 헤더에는 아래와 같이 값이 여러 개 있다고 가정합니다.

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

다음은 Accept 헤더에서 값을 읽는 자바스크립트 코드입니다.

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

위의 자바스크립트 코드는 Accept 헤더의 첫 번째 값(예: text/html)만 반환합니다.

예시 2: AssignMessage 또는 RaiseFault 정책의 다중 값 Access-Control-Allow-Headers 헤더 읽기

Access-Control-Allow-Headers 헤더에는 아래와 같이 값이 여러 개 있다고 가정합니다.

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

다음은 Access-Control-Allow-Headers 헤더를 설정하는 AssignMessage 또는 RaiseFault 정책의 코드 중 일부입니다.

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

위 코드는 요청 헤더 Access-Control-Allow-Headers의 첫 번째 값만 사용하여 Access-Control-Allow-Headers 헤더를 설정합니다(이 예시의 경우 content-type).

영향

  1. 위의 두 예에서는 다중 값 헤더의 첫 번째 값만 반환됩니다. 나중에 API 프록시 흐름의 다른 정책이나 백엔드 서비스에서 이러한 값을 사용하여 일부 함수 또는 로직을 수행하면 예기치 않은 결과 또는 결과가 발생할 수 있습니다.
  2. 액세스한 요청 헤더 값이 대상 서버로 전달되는 경우 API 요청은 백엔드에서 잘못 처리되어 잘못된 결과를 제공할 수 있습니다.
  3. 클라이언트 애플리케이션이 Edge 응답의 특정 헤더 값에 의존하는 경우 애플리케이션이 잘못 처리되어 잘못된 결과를 제공할 수도 있습니다.

권장사항

  1. request.header.header_name.values.count, request.header.header_name.N, response.header.header_name.values.count, response.header.header_name.N 등 적절한 기본 제공 흐름 변수를 사용합니다.

    그런 다음 반복하여 자바스크립트 또는 자바 콜아웃 정책의 특정 헤더에서 모든 값을 가져옵니다.

    예: 다중 값 헤더를 읽기 위한 샘플 자바스크립트 코드

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

    예를 들어 application/xml;q=0.9, */*;q=0.8는 위의 코드에서 하나의 값으로 표시됩니다.

    세미콜론을 구분기호로 헤더 값을 분할해야 하는 경우에는 string.split(";")을 사용하여 값을 구분합니다.

  2. RaiseFault 또는 AssignMessage 정책의 request.header.header_name.values 흐름 변수에서 substring() 함수를 사용하여 특정 헤더의 모든 값을 읽습니다.

    예: 다중 값 헤더를 읽기 위한 샘플 RaiseFault 또는 AssignMessage 정책

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

추가 자료