অ্যাক্সেস-কন্ট্রোল-মঞ্জুরি-উত্সের ওয়াইল্ডকার্ড সাবডোমেন, পোর্ট এবং প্রোটোকল


312

আমি সমস্ত সাবডোমেন, পোর্ট এবং প্রোটোকলের জন্য সিওআরএস সক্ষম করার চেষ্টা করছি।

উদাহরণস্বরূপ, আমি http://sub.mywebsite.com:8080/ থেকে https://www.mywebsite.com/ * তে একটি এক্সএইচআর অনুরোধ চালাতে সক্ষম হতে চাই

সাধারণত, আমি উত্স মিলের অনুরোধটি সক্ষম করতে চাই (এবং সীমাবদ্ধ):

//*.mywebsite.com:*/*

উত্তর:


207

ডেভর্যান্ডমের উত্তরের ভিত্তিতে , আমিও চারপাশে খেলছিলাম এবং কিছুটা সরল অ্যাপাচি সমাধান খুঁজে পেল যা কোনও ফলস্বরূপ Access-Control-Allow-Originকোনও নিয়ম ব্যবহার না করে একই ফলাফল ( বর্তমান নির্দিষ্ট প্রোটোকল + ডোমেন + পোর্টকে গতিশীলভাবে সেট করে) তৈরি করে:

SetEnvIf Origin ^(https?://.+\.mywebsite\.com(?::\d{1,5})?)$   CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin  %{CORS_ALLOW_ORIGIN}e   env=CORS_ALLOW_ORIGIN
Header merge  Vary "Origin"

এবং এটাই.

যাঁরা এর সমস্ত সাবডোমেনগুলি ছাড়াও প্যারেন্ট ডোমেনে (উদাঃ মাইয়েবসাইট ডটকম) CORS সক্ষম করতে চান তারা প্রথম লাইনে নিয়মিত প্রকাশটি কেবল এইটির সাথে প্রতিস্থাপন করতে পারেন:

^(https?://(?:.+\.)?mywebsite\.com(?::\d{1,5})?)$

দ্রষ্টব্য: নির্দিষ্ট মেনে চলার এবং সঠিক ক্যাশেয়ার আচরণের জন্য, সর্বদা Vary: OriginCORS- সক্ষম সংস্থানগুলির জন্য প্রতিক্রিয়া শিরোনাম যুক্ত করে , এমনকি নন-CORS অনুরোধ এবং অস্বীকৃত উত্স থেকে প্রাপ্তদের জন্য ( উদাহরণস্বরূপ কেন দেখুন )।


1
আমাদের প্রায় এটি ছিল (ভেরি অরিজিন নয়) এবং একই ফন্ট ব্যবহার করে একাধিক সাব ডোমেনের মধ্যে দর্শনার্থীরা ঝাঁপিয়ে পড়লে আমাদের খারাপ ব্যবহার হয়েছিল got ফন্ট এবং অ্যাক্সেস-নিয়ন্ত্রণ-উত্স শিরোনামটিও ক্যাশে করা হয়েছিল। আমি এটিতে কিছুটা পরিবর্তন করেছি: যদি অনুরোধটি আমাদের অনুমোদিত ডোমেনগুলির একটি থেকে অনুরোধ থাকে তবে আমি "অ্যাক্সেস-কন্ট্রোল-অলজন-অরিজিন *" ব্যবহার করি। সম্ভবত এটি "ভেরি অরিজিন" দিয়ে সমাধান করা হয়েছিল যা আমাদের আগে ছিল না ... এখন এটিও যুক্ত হয়েছে।
এরিক মেলকারসন

2
মূল ডোমেইন 'mywebsite.com' এর জন্য কাজ করে না
biolog.info

1
@ পিজিম্যান, //এই প্রসঙ্গে এড়াতে হবে না যেহেতু অ্যাপাচি কনফ স্ল্যাশ-বিস্মৃত নিয়মিত অভিব্যক্তি ব্যবহার করে না। রেজেক্সার অভিযোগ করেন কারণ, সেই প্রসঙ্গে, স্ল্যাশগুলির সীমানা হিসাবে বিশেষ অর্থ রয়েছে have
নয়েও

1
The 'Access-Control-Allow-Origin' header contains multiple values '^(https?://(?:.+.)?aerofotea.com(?::d{1,5})?)$', but only one is allowed. Origin 'http://local.aerofotea.com' is therefore not allowed access.
অ্যারো ওয়াং

3
আপনি এই কোডটি কোথায় রাখবেন? .htaccess বা অ্যাপাচে ভার্চুয়াল হোস্ট কনফিগারেশনে?
গ্লেন

252

সিওআরএস স্পেস হ'ল বা কিছুই নয়। এটা শুধুমাত্র সমর্থন *, nullবা সঠিক প্রোটোকল + + ডোমেইন + + পোর্ট: http://www.w3.org/TR/cors/#access-control-allow-origin-response-header

আপনার সার্ভারকে রেজিক্স ব্যবহার করে মূল শিরোনামটি বৈধতা দিতে হবে এবং তারপরে আপনি অ্যাক্সেস-কন্ট্রোল-মঞ্জুরি-উত্স প্রতিক্রিয়ার শিরোনামে মূল মানটি প্রতিধ্বনিত করতে পারেন।


7
@ ডেক্সটার "নাল" একটি "নাল" উত্সের প্রতিক্রিয়া হিসাবে ব্যবহার করা যেতে পারে, যেমন কোনও ফাইল: // স্কিমের সিওআরএস অনুরোধ করার সময়।
দৈত্য

130
এটি গভীরভাবে সংক্ষিপ্তভাবে দেখেছে যে সিওআরএস স্পিক ওপির সঠিক ব্যবহারের ক্ষেত্রে সমর্থন করবে না ।
আরথ

6
@ অ্যারোথ: সত্যই নয়, চশমা বাস্তবায়নগুলি তাদের পছন্দসই যেকোন ম্যাচিং সিনট্যাক্স ব্যবহার করতে দেয় ; এই প্রয়োগের ক্ষেত্রে সমর্থন না করার জন্য এটি বাস্তবায়নের জন্য কেবল গভীরভাবে আলোকপাত করা হবে । অন্য কথায়, আপনি আপনার সার্ভারে যা নির্দিষ্ট করেছেন সেটি ACAO মান নয়, পরবর্তীটি কেবলমাত্র একটি প্রোটোকল বিশদ। আমার ধারণাটি এমন যে কোনও সুরক্ষা পরিস্থিতি রয়েছে যা প্রয়োজন থেকে উত্স থেকে ফিরে প্রতিধ্বনিত হতে পারে তবে একটি নিষ্পাপ বাস্তবায়ন কেবল "ঠিক আছে" বা না বলে কাজ করে।
tne

3
২০১৫ সালের আপডেট: এই উত্তরটি ক্ষতিকারক হিসাবে বিবেচনা করা উচিত, কারণ এটি অসম্পূর্ণ এবং এটি ক্যাশে সংক্রান্ত সমস্যার কারণ হতে পারে। যথাযথ বাস্তবায়ন (ব্যাখ্যা) এবং ব্যাখ্যার জন্য দয়া করে নীচে আমার উত্তরটি দেখুন: stackoverflow.com/a/27990162/357774 । এছাড়াও, @aroth, যেমন tne তুলে ধরে, বৈশিষ্ট আসলে আছে : ওপি এর সঠিক ব্যবহারের ক্ষেত্রে অনুমতি w3.org/TR/cors/#resource-implementation । এবং যেমন এই উত্তরটি নির্দেশ করে, এটি প্রয়োগ করা সার্ভারের উপর নির্ভর করে। এটি 3 লাইনে করা যেতে পারে, যেমন উপরে বর্ণিত উত্তরে দেখা গেছে।
নভো

19
@ নাইও - আমি তখন আমার আসল অর্থটি পরিষ্কার করব। এটি গভীরভাবে সংক্ষিপ্তভাবে দেখেছে যে সিওআরএস স্পেকের পক্ষে ওপি-র সঠিক ব্যবহারের ক্ষেত্রে স্বয়ংক্রিয়, অন্তর্নির্মিত সমর্থন সরবরাহের জন্য CORS প্রয়োগকারী সমস্ত সার্ভারগুলির কঠোরভাবে প্রয়োজন হয় না । কাস্টম পিএইচপি কোড, পুনর্লিখনের বিধিগুলি বা কী কী আছে তা ব্যবহার করে তাদের নিজস্ব শিমটি তৈরি করতে প্রতিটি পৃথক ব্যবহারকারীর কাছে রেখে দেওয়া হ'ল বিভাজন, বাগ এবং বিপর্যয়ের একটি রেসিপি। সার্ভার ডেভস এর চেয়ে ভাল জানা উচিত; এবং যদি তারা তা না করে তবে কর্স স্পেক তাদের জোর করে।
আরথ

59

সম্পাদনা : এটির পরিবর্তে @ নওয়ের সমাধানটি ব্যবহার করুন। এটি সহজ, পরিষ্কার এবং লোডের নিচে সম্ভবত আরও অনেক পারফরম্যান্ট।

মূল উত্তরটি কেবলমাত্র Pতিহাসিক উদ্দেশ্যগুলির জন্য এখানে বামে !!


আমি এই সমস্যাটি নিয়ে কিছুটা খেলছিলাম এবং এই পুনরায় ব্যবহারযোগ্য .htaccess (বা httpd.conf) সমাধান নিয়ে এসেছি যা অ্যাপাচি নিয়ে কাজ করে:

<IfModule mod_rewrite.c>
<IfModule mod_headers.c>
    # Define the root domain that is allowed
    SetEnvIf Origin .+ ACCESS_CONTROL_ROOT=yourdomain.com

    # Check that the Origin: matches the defined root domain and capture it in
    # an environment var if it does
    RewriteEngine On
    RewriteCond %{ENV:ACCESS_CONTROL_ROOT} !=""
    RewriteCond %{ENV:ACCESS_CONTROL_ORIGIN} =""
    RewriteCond %{ENV:ACCESS_CONTROL_ROOT}&%{HTTP:Origin} ^([^&]+)&(https?://(?:.+?\.)?\1(?::\d{1,5})?)$
    RewriteRule .* - [E=ACCESS_CONTROL_ORIGIN:%2]

    # Set the response header to the captured value if there was a match
    Header set Access-Control-Allow-Origin %{ACCESS_CONTROL_ORIGIN}e env=ACCESS_CONTROL_ORIGIN
</IfModule>
</IfModule>

কেবলমাত্র ACCESS_CONTROL_ROOTআপনার মূল ডোমেনে ব্লকের শীর্ষে চলকটি সেট করুন এবং এটি যদি আপনার ডোমেনের সাথে মিলে যায় তবে এটি প্রতিক্রিয়া শিরোনামের মানটিতে Origin:ক্লায়েন্টের কাছে অনুরোধ শিরোনামের মানটি প্রতিধ্বনিত করবে Access-Control-Allow-Origin:

নোট এছাড়াও আপনি ব্যবহার করতে পারেন sub.mydomain.comযেমন ACCESS_CONTROL_ROOTএবং এটি উদ্ভব সীমাবদ্ধ করবে sub.mydomain.comএবং *.sub.mydomain.com(ie এটা ডোমেইন রুট হতে হবে না)। যে উপাদানগুলিকে পরিবর্তিত হতে দেওয়া হয় (প্রোটোকল, পোর্ট) তা রেগেক্সের ইউআরআই ম্যাচিং অংশটি সংশোধন করে নিয়ন্ত্রণ করা যায়।


22

আমি এই প্রশ্নের উত্তর দিচ্ছি, কারণ গৃহীত উত্তরগুলি নিম্নলিখিতটি করতে পারে না

  1. রেজেক্স গ্রুপিং একটি পারফরম্যান্স হিট , এটি প্রয়োজনীয় নয়।
  2. প্রাথমিক ডোমেনটির সাথে মেলে না এবং এটি কেবল সাব ডোমেনের জন্য কাজ করে।

উদাহরণস্বরূপ: http://somedomain.mywebsite.com/ এর জন্য কাজ করার সময় এটি http://mywebsite.com এর জন্য সিওআরএস শিরোনাম প্রেরণ করবে না while

SetEnvIf Origin "http(s)?://(.+\.)?mywebsite\.com(:\d{1,5})?$" CORS=$0

Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS
Header merge  Vary "Origin"

আপনার সাইটের জন্য সক্ষম করতে, আপনি কেবল উপরের অ্যাপাচি কনফিগারেশনে আপনার সাইটটি "mywebsite.com" এর জায়গায় রেখেছেন।

একাধিক সাইটকে অনুমতি দেওয়ার জন্য:

SetEnvIf Origin "http(s)?://(.+\.)?(othersite\.com|mywebsite\.com)(:\d{1,5})?$" CORS=$0

স্থাপনার পরে পরীক্ষা করা:

নিম্নলিখিত কার্ল প্রতিক্রিয়ার পরিবর্তনের পরে "অ্যাক্সেস-নিয়ন্ত্রণ-অনুমতি দিন" মূল শিরোনাম থাকা উচিত।

curl -X GET -H "Origin: http://examplesite1.com" --verbose http://examplesite2.com/query

12

আমার একটি পিএইচপি-কেবলমাত্র সমাধান প্রয়োজন, তাই কেবল যদি কারওর প্রয়োজন হয়। এটি "* .example.com" এর মতো অনুমোদিত ইনপুট স্ট্রিং নেয় এবং যদি ইনপুট মেলে তবে অনুরোধ শিরোনাম সার্ভারের নামটি দেয়।

function getCORSHeaderOrigin($allowed, $input)
{
    if ($allowed == '*') {
        return '*';
    }

    $allowed = preg_quote($allowed, '/');

    if (($wildcardPos = strpos($allowed, '*')) !== false) {
        $allowed = str_replace('*', '(.*)', $allowed);
    }

    $regexp = '/^' . $allowed . '$/';

    if (!preg_match($regexp, $input, $matches)) {
        return 'none';
    }

    return $input;
}

এবং এখানে phpunit ডেটা সরবরাহকারীর জন্য পরীক্ষার কেসগুলি রয়েছে:

//    <description>                            <allowed>          <input>                   <expected>
array('Allow Subdomain',                       'www.example.com', 'www.example.com',        'www.example.com'),
array('Disallow wrong Subdomain',              'www.example.com', 'ws.example.com',         'none'),
array('Allow All',                             '*',               'ws.example.com',         '*'),
array('Allow Subdomain Wildcard',              '*.example.com',   'ws.example.com',         'ws.example.com'),
array('Disallow Wrong Subdomain no Wildcard',  '*.example.com',   'example.com',            'none'),
array('Allow Double Subdomain for Wildcard',   '*.example.com',   'a.b.example.com',        'a.b.example.com'),
array('Don\'t fall for incorrect position',    '*.example.com',   'a.example.com.evil.com', 'none'),
array('Allow Subdomain in the middle',         'a.*.example.com', 'a.bc.example.com',       'a.bc.example.com'),
array('Disallow wrong Subdomain',              'a.*.example.com', 'b.bc.example.com',       'none'),
array('Correctly handle dots in allowed',      'example.com',     'exampleXcom',            'none'),

1
+1, ব্যবহারের জন্য সম্পাদিত preg_quote()কারণ এটি করার সঠিক উপায় এটি (যদিও .ডিএনএস নামে একমাত্র রেজিপ্সপ মেটা চর বৈধ, preg_quote()
অভিযুক্ত

1
এটি স্পষ্ট করে noneবলা উচিত যে হেডারের জন্য শব্দার্থগতভাবে বৈধ মান নয় (বা কমপক্ষে, এটি যা বোঝায় তা করে না) অনুমান অনুসারে। যেমনটি, return null;সেই শাখার জন্য আরও অর্থবোধ করতে পারে এবং সেই ক্ষেত্রে কোনও শিরোনাম ক্লায়েন্টের কাছে প্রেরণ করা উচিত নয়, তাই এটি কলকারী দ্বারা পরীক্ষা করা উচিত।
ডেভর্যান্ডম

preg_quote()* চিহ্নটি উদ্ধৃত করবে এবং str_replace()উদাহরণস্বরূপ একটি অনাথ "\" ছেড়ে যায়।
ক্রিস্টোফার বুবাচ

1
এটি দরকারী, আমি সিওআরএস ইস্যুতে সময় কাটিয়েছি যতক্ষণ না বুঝলাম যে আমার সাইটের এজাক্সে "www" রয়েছে তবে পারমিলিক স্ট্রাকচারে নয় - আপনার সমাধানটি আমাকে বুঝতে সমস্যাটি কোথায় ছিল এবং এটি আমার জন্য সমাধান করেছে।
সল

3

Access-Control-Allow-Origin.Htaccess স্থাপন করার সময় , কেবলমাত্র নিম্নলিখিতটি কাজ করেছিল:

SetEnvIf Origin "http(s)?://(.+\.)?domain\.com(:\d{1,5})?$" CRS=$0
Header always set Access-Control-Allow-Origin "%{CRS}e" env=CRS

আমি চেষ্টা বেশ কয়েকটি প্রস্তাব কীওয়ার্ড Header append, Header set, কেউ কাজ করেন তাই অনেক উত্তর প্রস্তাব, যদিও আমি মনে করি নহি এই কীওয়ার্ড অচল হয়ে থাকে অথবা জন্য বৈধ নয় যদি nginx

এখানে আমার সম্পূর্ণ সমাধান:

SetEnvIf Origin "http(s)?://(.+\.)?domain\.com(:\d{1,5})?$" CRS=$0
Header always set Access-Control-Allow-Origin "%{CRS}e" env=CRS
Header merge Vary "Origin"

Header always set Access-Control-Allow-Methods "GET, POST"
Header always set Access-Control-Allow-Headers: *

# Cached for a day
Header always set Access-Control-Max-Age: 86400

RewriteEngine On

# Respond with 200OK for OPTIONS
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

2

"কুকি ডোমেন" (www.domain.tld) ​​থেকে ফন্টগুলি পড়ার সময় আমাদের স্ট্যাটিক "কুকি-কম" ডোমেনে ফন্ট আশ্চর্যর সাথে একই রকম সমস্যা ছিল এবং এই পোস্টটি আমাদের নায়ক ছিল। এখানে দেখুন: আমি কীভাবে 'মিসিং ক্রস-অরিজিন রিসোর্স শেয়ারিং (সিওআরএস) প্রতিক্রিয়া শিরোনাম' ওয়েবফন্ট ইস্যুটি ঠিক করতে পারি?

অনুলিপি / পেস্ট-আর প্রকারের জন্য (এবং কিছু প্রপস দেওয়ার জন্য) আমি এগুলি সমস্ত অবদান থেকে একসাথে পাই এবং এটি সাইটের মূলের .htaccess ফাইলের শীর্ষে যুক্ত করেছি:

<IfModule mod_headers.c>
 <IfModule mod_rewrite.c>
    SetEnvIf Origin "http(s)?://(.+\.)?(othersite\.com|mywebsite\.com)(:\d{1,5})?$" CORS=$0
    Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS
    Header merge  Vary "Origin"
 </IfModule>
</IfModule>

সুপার সিকিউর, সুপার এলিগ্যান্ট। এটি পছন্দ করুন: চোর / হট-লিঙ্ক-এআর ধরণের সংস্থানগুলিতে আপনাকে আপনার সার্ভার ব্যান্ডউইদথ খুলতে হবে না।

প্রপস: @ নয়েও @ ডেভর্যান্ডম @ প্রতাপ-কোরিটলা

(আমি গ্রহণযোগ্য উত্তরের মন্তব্য হিসাবে এটি ছেড়ে দেওয়ার চেষ্টা করেছি, তবে আমি এখনও এটি করতে পারি না)



0

দেখে মনে হচ্ছে আসল উত্তরটি প্রাক অ্যাপাচি ২.৪ এর জন্য ছিল। এটা আমার জন্য কাজ করে নি। এটি ২.৪-এ কাজ করার জন্য আমাকে যা পরিবর্তন করতে হয়েছিল তা এখানে। এটি এর সাবডোমেন কোন গভীরতা জন্য কাজ করবে yourcompany.com

SetEnvIf Host ^((?:.+\.)*yourcompany\.com?)$    CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin  %{REQUEST_SCHEME}e://%{CORS_ALLOW_ORIGIN}e    env=CORS_ALLOW_ORIGIN
Header merge  Vary "Origin"

0

একটি অনাথ অনাথী হিসাবে রেগেক্সে শেষ হওয়ার পরে আমাকে লার্সের উত্তরকে কিছুটা সংশোধন \করতে হয়েছিল, কেবল প্রকৃত হোস্টের সাথে তুলনা করতে (প্রোটোকল বা বন্দরের দিকে মনোযোগ দিচ্ছে না) এবং আমি localhostআমার প্রোডাকশন ডোমেন ছাড়াও ডোমেন সমর্থন করতে চেয়েছিলাম । এইভাবে আমি $allowedপরামিতিটিকে অ্যারে হিসাবে পরিবর্তন করেছি ।

function getCORSHeaderOrigin($allowed, $input)
{
    if ($allowed == '*') {
        return '*';
    }

    if (!is_array($allowed)) {
        $allowed = array($allowed);
    }

    foreach ($allowed as &$value) {
        $value = preg_quote($value, '/');

        if (($wildcardPos = strpos($value, '\*')) !== false) {
            $value = str_replace('\*', '(.*)', $value);
        }
    }

    $regexp = '/^(' . implode('|', $allowed) . ')$/';

    $inputHost = parse_url($input, PHP_URL_HOST);

    if ($inputHost === null || !preg_match($regexp, $inputHost, $matches)) {
        return 'none';
    }

    return $input;
}

নিম্নলিখিত হিসাবে ব্যবহার:

if (isset($_SERVER['HTTP_ORIGIN'])) {
    header("Access-Control-Allow-Origin: " . getCORSHeaderOrigin(array("*.myproduction.com", "localhost"), $_SERVER['HTTP_ORIGIN']));
}

0

আমার ক্ষেত্রে কৌনিক ব্যবহার করে

আমার এইচটিটিপি ইন্টারসেপ্টারে আমি সেট করেছিলাম

with Credentials: true.

অনুরোধ শিরোনামে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.