Antipattern: एपीआई प्रॉक्सी में, एक से ज़्यादा वैल्यू वाले एचटीटीपी हेडर को गलत तरीके से ऐक्सेस करें

Apigee Edge दस्तावेज़ देखा जा रहा है.
Apigee X दस्तावेज़ पर जाएं.
जानकारी

एचटीटीपी हेडर, नेम वैल्यू पेयर होते हैं. इनकी मदद से, क्लाइंट ऐप्लिकेशन और बैकएंड सेवाएं, अनुरोध और रिस्पॉन्स के बारे में ज़्यादा जानकारी भेज सकती हैं. यहां कुछ सामान्य उदाहरण दिए गए हैं:

  • अनुमति देने के अनुरोध का हेडर, उपयोगकर्ता के क्रेडेंशियल को सर्वर पर भेजता है:
    Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
  • Content-Type हेडर से पता चलता है कि भेजा जा रहा अनुरोध/जवाब का कॉन्टेंट किस तरह का है:
    Content-Type: application/json

एचटीटीपी हेडर में एक या उससे ज़्यादा वैल्यू हो सकती हैं. ये वैल्यू, हेडर फ़ील्ड की परिभाषाओं के आधार पर तय होती हैं. एक से ज़्यादा वैल्यू वाले हेडर में, कॉमा लगाकर अलग की गई वैल्यू होंगी. यहां ऐसे हेडर के कुछ उदाहरण दिए गए हैं जिनमें एक से ज़्यादा वैल्यू होती हैं:

  • 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

JavaScript ऑब्जेक्ट:

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

यहां AttributionMessage नीति का उदाहरण दिया गया है, जिसमें अनुरोध के हेडर की वैल्यू को पढ़ने और उसे किसी वैरिएबल में स्टोर करने का तरीका बताया गया है:

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

एंटीपैटर्न

Edge की नीतियों में एचटीटीपी हेडर की वैल्यू को इस तरह ऐक्सेस करना कि सिर्फ़ पहली वैल्यू दिखाई जाए, गलत हो. साथ ही, किसी खास एचटीटीपी हेडर की एक से ज़्यादा वैल्यू होने पर समस्या हो सकती है.

नीचे दिए गए सेक्शन में हेडर ऐक्सेस के उदाहरण दिए गए हैं.

उदाहरण 1: JavaScript कोड का इस्तेमाल करके, कई वैल्यू वाला 'स्वीकार करें' हेडर पढ़ें

मान लें कि Accept हेडर में एक से ज़्यादा वैल्यू हैं, जैसा कि यहां दिखाया गया है:

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

Accept हेडर की वैल्यू को पढ़ने वाला JavaScript कोड यह है:

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

ऊपर दिया गया JavaScript कोड, Accept हेडर से सिर्फ़ पहली वैल्यू दिखाता है, जैसे कि text/html.

उदाहरण 2: assignMessage या केसFault की नीति में कई वैल्यू वाला Access-Control-Allow-Headers हेडर पढ़ें

मान लें कि Access-Control-Allow-Headers हेडर में एक से ज़्यादा वैल्यू हैं, जैसा कि यहां दिखाया गया है:

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

Access-Control-Allow-Headers हेडर को असाइन करने के लिए मैसेज या riseFault की नीति को सेट करने के कोड का हिस्सा यहां दिया गया है:

<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. ध्यान दें कि ऊपर दिए गए दोनों उदाहरणों में, बहु-वैल्यू वाले हेडर का सिर्फ़ पहला वैल्यू दिखाया जाता है. अगर एपीआई प्रॉक्सी फ़्लो में कोई दूसरी नीति या बैकएंड सेवा, इन वैल्यू का इस्तेमाल बाद में किसी फ़ंक्शन या लॉजिक को करने के लिए करती है, तो इससे अनचाहा नतीजा मिल सकता है.
  2. जब अनुरोध के हेडर की वैल्यू को ऐक्सेस करके टारगेट सर्वर पर भेजा जाता है, तो हो सकता है कि बैकएंड, एपीआई अनुरोधों को गलत तरीके से प्रोसेस करे. इस वजह से, वे गलत नतीजे दे सकते हैं.
  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.

    इसके बाद, JavaScript या Java की कॉलआउट नीतियों में, किसी खास हेडर से सभी वैल्यू को फिर से फ़ेच करें.

    उदाहरण: कई वैल्यू वाले हेडर को पढ़ने के लिए JavaScript कोड का सैंपल

    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. किसी खास हेडर की सभी वैल्यू को पढ़ने के लिए, riseFault या याassignMessage नीति के फ़्लो वैरिएबल request.header.header_name.values पर substring() फ़ंक्शन का इस्तेमाल करें.

    उदाहरण: बहु-वैल्यू वाला हेडर पढ़ने के लिए सैंपल riseFault या AssignmentsMessage Policy

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

इसके बारे में और पढ़ें