API প্রক্সিতে CORS সাপোর্ট যোগ করা

আপনি Apigee Edge ডকুমেন্টেশন দেখছেন।
Apigee X ডকুমেন্টেশন দেখুন।
তথ্য

CORS (ক্রস-অরিজিন রিসোর্স শেয়ারিং) হল একটি স্ট্যান্ডার্ড মেকানিজম যা জাভাস্ক্রিপ্ট XMLHttpRequest (XHR) কলকে ওয়েবপেজে এক্সিকিউট করে, যাতে নন-অরিজিন ডোমেনের রিসোর্সের সাথে ইন্টার‍্যাক্ট করা যায়। CORS হল "একই-উৎস নীতি" সংক্রান্ত সমস্যার একটি সাধারণ সমাধান যা সব ব্রাউজার দ্বারা প্রয়োগ করা হয়। যেমন, আপনার ব্রাউজারে এক্সিকিউট করা জাভাস্ক্রিপ্ট কোড থেকে Twitter API-তে XHR কল করলে কলটি ব্যর্থ হবে। এর কারণ হল, আপনার ব্রাউজারকে যে ডোমেন পৃষ্ঠা পরিবেশন করছে সেটি Twitter API পরিবেশনকারী ডোমেনের মতো নয়। ক্রস-অরিজিন রিসোর্স শেয়ারিং করতে চাইলে, সার্ভারকে "অপট-ইন" করার অনুমতি দিয়ে CORS এই সমস্যার সমাধান করে।

ভিডিও: API প্রক্সিতে কীভাবে CORS চালু করতে হয় তা জানতে একটি ছোট ভিডিও দেখুন।

CORS-এর সাধারণ ব্যবহার

নিচে উল্লেখ করা JQuery কোড একটি কাল্পনিক টার্গেট পরিষেবাকে কল করে। কোনও ব্রাউজারের (ওয়েবপেজ) মধ্যে থেকে এটি এক্সিকিউট করা হলে, একই অরিজিন সংক্রান্ত নীতির কারণে কলটি কাজ করবে না:

<script>
var url = "http://service.example.com";
$(document).ready(function(){
  $("button").click(function(){
    $.ajax({
        type:"GET",
        url:url,
        async:true,
        dataType: "json",
           success: function(json) {
              // Parse the response.
              // Do other things.
           },
           error: function(xhr, status, err) {
              // This is where we end up!
            }
    });
  });
});
</script>

এই সমস্যার একটি সমাধান হল, Apigee API প্রক্সি তৈরি করা যা ব্যাক-এন্ডে পরিষেবা API-কে কল করে। মনে রাখবেন, Edge ক্লায়েন্ট (এই ক্ষেত্রে একটি ব্রাউজার) এবং ব্যাকএন্ড API (পরিষেবা)-এর মধ্যে থাকে। API প্রক্সি সার্ভারে এক্সিকিউট হয়, ব্রাউজারে নয়, তাই এটি সফলভাবে পরিষেবা কল করতে পারে। তারপরে, আপনাকে যা করতে হবে তা হল TargetEndpoint রেসপন্সে CORS হেডার অ্যাটাচ করতে হবে। যতক্ষণ ব্রাউজার CORS-কে সমর্থন করে, এইসব হেডার ব্রাউজারকে সিগন্যাল দেয় যে এটি একই-উৎস নীতি "শিথিল" করতে পারে, এর ফলে ক্রস-অরিজিন API কল সফল হয়।

CORS কাজ করে এমন প্রক্সি তৈরি হয়ে গেলে, আপনার ক্লায়েন্ট-সাইড কোডে ব্যাকএন্ড সার্ভিসের পরিবর্তে API প্রক্সি URL কল করতে পারবেন। যেমন:

<script>
var url = "http://myorg-test.apigee.net/v1/example";
$(document).ready(function(){
  $("button").click(function(){
    $.ajax({
        type:"GET",
        url:url,
        async:true,
        dataType: "json",
           success: function(json) {
              // Parse the response.
              // Do other things.
           },
           error: function(xhr, status, err) {
              // This time, we do not end up here!
            }
    });
  });
});
</script>

নতুন API প্রক্সিতে CORS নীতি যোগ করা

আপনি API প্রক্সি তৈরি করার সময়, API প্রক্সিতে "CORS যোগ করুন" নীতি অ্যাটাচ করে API প্রক্সিতে CORS সাপোর্ট যোগ করতে পারেন। এই নীতি যোগ করতে, 'প্রক্সি উইজার্ড তৈরি করুন' বিকল্পের নিরাপত্তা পৃষ্ঠায় CORS হেডার যোগ করুন চেকবক্স বেছে নিন।

আপনি এই চেকবক্স বেছে নিলে, Add CORS নামের একটি নীতি অটোমেটিক সিস্টেমে যোগ করা হয় এবং TargetEndpoint রেসপন্স প্রিফ্লোতে অ্যাটাচ করা হয়, যেমনটি নিম্নলিখিত ছবিতে দেখানো হয়েছে:

ডানদিকের প্যানেলে 'নীতি' বিকল্পের অধীনে নেভিগেটরে CORS নীতি যোগ করা হয়েছে এবং TargetEndpoint রেসপন্স প্রিফ্লোতে অ্যাটাচ করা হয়েছে

Add CORS নীতিটি AssignMessage নীতি হিসেবে প্রয়োগ করা হয়, যা উত্তরে উপযুক্ত হেডার যোগ করে। মোটকথা, হেডার ব্রাউজারকে জানায় যে কোন কোন অরিজিনের সাথে রিসোর্স শেয়ার করা হবে, কোন কোন পদ্ধতি গ্রহণ করা হবে ইত্যাদি। আপনি এইসব CORS হেডার সম্পর্কে ক্রস-অরিজিন রিসোর্স শেয়ারিং W3C সাজেশন থেকে আরও পড়তে পারেন।

আপনাকে নিম্নলিখিতভাবে নীতি পরিবর্তন করতে হবে:

  • নিচের কোড স্নিপেটে দেখানো Access-Control-Allow-Headers হেডারে content-type ও authorization হেডার যোগ করুন (বেসিক যাচাইকরণ বা OAuth2-এর জন্য প্রয়োজন)।
  • OAuth2 যাচাইকরণের জন্য, আপনাকে RFC-এর সাথে সঙ্গতিপূর্ণ নয় এমন আচরণ সংশোধন করার জন্য পদক্ষেপ নিতে হতে পারে।
  • নিচে দেওয়া উদাহরণে দেখানো <Add>-এর পরিবর্তে CORS হেডার সেট করার জন্য <Set> ব্যবহার করার জন্য সাজেস্ট করা হয়। <Add> ব্যবহার করার সময়, Access-Control-Allow-Origin হেডার আগে থেকেই থাকলে, আপনি নিম্নলিখিত সমস্যা সংক্রান্ত মেসেজ পাবেন:

    The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.

    আরও তথ্যের জন্য, CORS Error : header contains multiple values '*, *', but only one is allowed দেখুন।

<AssignMessage async="false" continueOnError="false" enabled="true" name="add-cors">
    <DisplayName>Add CORS</DisplayName>
    <FaultRules/>
    <Properties/>
    <Set>
        <Headers>
            <Header name="Access-Control-Allow-Origin">{request.header.origin}</Header>
            <Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type, authorization</Header>
            <Header name="Access-Control-Max-Age">3628800</Header>
            <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
        </Headers>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

আগে থেকে থাকা প্রক্সিতে CORS হেডার যোগ করা

আপনাকে ম্যানুয়ালি একটি নতুন Assign Message নীতি তৈরি করতে হবে এবং আগের বিভাগে তালিকাভুক্ত Add CORS নীতির কোডটি এতে কপি করতে হবে। তারপরে, API প্রক্সির TargetEndpoint-এর রেসপন্স প্রিফ্লোতে নীতিটি অ্যাটাচ করুন। প্রয়োজন অনুযায়ী আপনি হেডার ভ্যালু পরিবর্তন করতে পারবেন। নীতি তৈরি ও অ্যাটাচ করা সম্পর্কে আরও তথ্য পেতে, নীতি কী? দেখুন।

CORS প্রিফ্লাইট অনুরোধ ম্যানেজ করা

CORS প্রিফ্লাইট বলতে কোনও সার্ভারে অনুরোধ পাঠিয়ে এটি CORS কাজ করে কিনা তা যাচাই করাকে বোঝায়। সাধারণত, প্রিফ্লাইট উত্তরে কোন কোন অরিজিন থেকে সার্ভার CORS অনুরোধ গ্রহণ করবে, CORS অনুরোধের জন্য কাজ করে এমন HTTP পদ্ধতির তালিকা, রিসোর্স অনুরোধের অংশ হিসেবে ব্যবহার করা যেতে পারে এমন হেডার, প্রিফ্লাইট উত্তর সর্বাধিক কতক্ষণ ক্যাশে করা হবে এবং অন্যান্য বিষয় অন্তর্ভুক্ত থাকে। পরিষেবাটি CORS কাজ করে না বলে জানালে অথবা ক্লায়েন্টের অরিজিন থেকে ক্রস-অরিজিন অনুরোধ গ্রহণ করতে না চাইলে, ব্রাউজারের ক্রস-অরিজিন নীতি প্রয়োগ করা হবে এবং সেই সার্ভারে হোস্ট করা রিসোর্সের সাথে ইন্টার‍্যাক্ট করার জন্য ক্লায়েন্ট কোনও ক্রস-ডোমেন অনুরোধ করলে তা কাজ করবে না।

সাধারণত, CORS প্রিফ্লাইট অনুরোধ HTTP OPTIONS পদ্ধতির মাধ্যমে করা হয়। CORS কাজ করে এমন কোনও সার্ভার OPTIONS অনুরোধ পেলে, সেটি ক্লায়েন্টকে CORS হেডার সেট রিটার্ন করে যা CORS কাজ করার লেভেল নির্দেশ করে। এই হ্যান্ডশেকের ফলে, ক্লায়েন্ট জানতে পারে যে এটি নন-অরিজিন ডোমেন থেকে কী অনুরোধ করতে পারবে।

প্রিফ্লাইট সম্পর্কে আরও তথ্যের জন্য, ক্রস-অরিজিন রিসোর্স শেয়ারিং W3C সাজেশন দেখুন। এছাড়াও, CORS-এর উপর অসংখ্য ব্লগ ও নিবন্ধ রয়েছে যা আপনি দেখতে পারেন।

Apigee-তে CORS প্রিফ্লাইট সলিউশন আগে থেকেই অন্তর্ভুক্ত থাকে না, তবে এই বিভাগে বর্ণিত পদ্ধতি অনুসরণ করে এটি ইমপ্লিমেন্ট করা সম্ভব। উদ্দেশ্য হল, প্রক্সি যেন কন্ডিশনাল ফ্লোতে OPTIONS অনুরোধ মূল্যায়ন করতে পারে। প্রক্সি তারপরে ক্লায়েন্টকে উপযুক্ত উত্তর পাঠাতে পারে।

আসুন, একটি স্যাম্পেল ফ্লো দেখে নিই এবং তারপর প্রিফ্লাইট অনুরোধ ম্যানেজ করা অংশগুলি নিয়ে আলোচনা করি:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <Flows>
        <Flow name="OptionsPreFlight">
            <Request/>
            <Response>
                <Step>
                    <Name>add-cors</Name>
                </Step>
            </Response>
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
        </Flow>
    </Flows>

    <PreFlow name="PreFlow">
        <Request/>
        <Response/>

    </PreFlow>
    <HTTPProxyConnection>
        <BasePath>/v1/cnc</BasePath>
        <VirtualHost>default</VirtualHost>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="NoRoute">
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </RouteRule>
    <RouteRule name="default">
        <TargetEndpoint>default</TargetEndpoint>
   </RouteRule>
   <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
</ProxyEndpoint>

এই ProxyEndpoint-এর মূল অংশগুলি হল:

  • OPTIONS অনুরোধের শর্ত সহ একটি NULL টার্গেটে RouteRule তৈরি করা হয়। মনে রাখবেন যে কোনও TargetEndpoint নির্দিষ্ট করা নেই। OPTIONS অনুরোধ পেলে এবং Origin ও Access-Control-Request-Method অনুরোধ হেডার শূন্য না হলে, প্রক্সি অবিলম্বে ক্লায়েন্টকে উত্তরে CORS হেডার রিটার্ন করে (প্রকৃত ডিফল্ট "ব্যাকএন্ড" টার্গেটকে বাইপাস করে)। ফ্লো কন্ডিশন ও RouteRule সম্পর্কে বিস্তারিত জানতে, ফ্লো ভেরিয়েবল সহ কন্ডিশন দেখুন।

    <RouteRule name="NoRoute">
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </RouteRule>
  • OPTIONS অনুরোধ পেলে এবং Origin ও Access-Control-Request-Method অনুরোধ হেডার শূন্য না হলে, CORS হেডার সহ একটি CORS নীতি ফ্লোতে যোগ করার জন্য একটি OptionsPreFlight ফ্লো তৈরি করা হয়।

     <Flow name="OptionsPreFlight">
                <Request/>
                <Response>
                    <Step>
                        <Name>add-cors</Name>
                    </Step>
                </Response>
            <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
     </Flow>

CORS সমাধানের নমুনা ব্যবহার করা

শেয়ার করা ফ্লো হিসেবে প্রয়োগ করা CORS সমাধানের একটি নমুনা GitHub-এ উপলভ্য। আপনার এনভায়রনমেন্টে শেয়ার করা ফ্লো বান্ডেল ইমপোর্ট করুন এবং ফ্লো হুক ব্যবহার করে বা সরাসরি API প্রক্সি ফ্লোতে এটি অ্যাটাচ করুন। আরও বিবরণের জন্য, স্যাম্পেলের সাথে দেওয়া CORS-Shared-FLow README ফাইল দেখুন।