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

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

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

مثال 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: یک سرصفحه 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 یا توسط سرویس پشتیبان برای انجام برخی عملکردها یا منطق مورد استفاده قرار گیرند، ممکن است منجر به یک نتیجه یا نتیجه غیرمنتظره شود.
  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. از تابع substring() در متغیر flow 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>
    

در ادامه مطلب