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

यह Apigee Edge का दस्तावेज़ है.
Go to the Apigee X documentation.
info

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

  • ऑथराइज़ेशन अनुरोध का हेडर, उपयोगकर्ता की क्रेडेंशियल जानकारी सर्वर को पास करता है:
    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

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

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

ऐंटीपैटर्न

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

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

पहला उदाहरण: JavaScript कोड का इस्तेमाल करके, एक से ज़्यादा वैल्यू वाले Accept हेडर को पढ़ना

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

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

यहां JavaScript कोड दिया गया है, जो Accept हेडर से वैल्यू पढ़ता है:

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

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

दूसरा उदाहरण: AssignMessage या RaiseFault नीति में, एक से ज़्यादा वैल्यू वाले Access-Control-Allow-Headers हेडर को पढ़ना

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

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

यहां AssignMessage या RaiseFault नीति का वह हिस्सा दिया गया है जो Access-Control-Allow-Headers हेडर सेट करता है:

<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. किसी खास हेडर की सभी वैल्यू को पढ़ने के लिए, 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>

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