Antipattern: به هدرهای HTTP چند ارزشی به اشتباه در یک پروکسی API دسترسی پیدا کنید

شما در حال مشاهده مستندات Apigee Edge هستید.
به مستندات Apigee X مراجعه کنید .
اطلاعات

هدرهای HTTP جفت‌های نام و مقدار هستند که به برنامه‌های کلاینت و سرویس‌های backend اجازه می‌دهند تا به ترتیب اطلاعات اضافی در مورد درخواست‌ها و پاسخ‌ها را ارسال کنند. چند مثال ساده عبارتند از:

  • هدر درخواست مجوز، اعتبارنامه‌های کاربر را به سرور ارسال می‌کند:
    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 در سیاست‌های Edge به روشی که فقط مقدار اول را برگرداند، نادرست است و اگر هدر(های) HTTP خاص بیش از یک مقدار داشته باشد، می‌تواند مشکلاتی ایجاد کند.

بخش‌های زیر شامل نمونه‌هایی از دسترسی به هدر هستند.

مثال ۱: خواندن یک هدر 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 را برمی‌گرداند.

مثال ۲: خواندن یک هدر Access-Control-Allow-Headers چند مقداری در سیاست AssignMessage یا RaiseFault

در نظر بگیرید که هدر 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>

کد بالا Header Access-Control-Allow-Headers تنها با اولین مقدار از هدر درخواست Access-Control-Allow-Headers ، در این مثال content-type ، تنظیم می‌کند.

تأثیر

  1. در هر دو مثال بالا، توجه داشته باشید که فقط اولین مقدار از هدرهای چند مقداری برگردانده می‌شود. اگر این مقادیر متعاقباً توسط سیاست دیگری در جریان API Proxy یا توسط سرویس backend برای انجام برخی عملکردها یا منطق‌ها استفاده شوند، می‌تواند منجر به نتیجه یا پیامد غیرمنتظره‌ای شود.
  2. وقتی مقادیر هدر درخواست مورد دسترسی قرار می‌گیرند و به سرور هدف ارسال می‌شوند، درخواست‌های API می‌توانند توسط backend به طور نادرست پردازش شوند و از این رو ممکن است نتایج نادرستی ارائه دهند.
  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. از تابع substring() روی متغیر جریان request.header. header_name .values ​​در سیاست RaiseFault یا AssignMessage برای خواندن تمام مقادیر یک هدر خاص استفاده کنید.

    مثال: نمونه‌ای از سیاست RaiseFault یا AssignMessage برای خواندن یک هدر چند مقداری

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

مطالعه بیشتر