प्रवेश-नियंत्रण-अनुमति-उत्पत्ति कई मूल डोमेन?


1049

क्या Access-Control-Allow-Originहेडर का उपयोग करके कई क्रॉस-डोमेन की अनुमति देने का एक तरीका है ?

मुझे इसकी जानकारी है *, लेकिन यह बहुत खुला है। मैं वास्तव में सिर्फ एक दो डोमेन की अनुमति देना चाहता हूं।

एक उदाहरण के रूप में, कुछ इस तरह:

Access-Control-Allow-Origin: http://domain1.example, http://domain2.example

मैंने उपरोक्त कोड की कोशिश की है, लेकिन यह फ़ायरफ़ॉक्स में काम नहीं करता है।

क्या कई डोमेन निर्दिष्ट करना संभव है या क्या मैं सिर्फ एक के साथ फंस गया हूं?



3
सबसे हाल ही में फ़ायरफ़ॉक्स का उपयोग करना, न तो अल्पविराम अलग किया गया, न ही अंतरिक्ष अलग डोमेन ने काम किया। डोमेन की सूची के खिलाफ मिलान करना और हेडर में एक ही होस्ट डालना अभी भी बेहतर सुरक्षा है और ठीक से काम नहीं करता है।
डैनियल डब्ल्यू।

1
यदि आप HTTPS के लिए इससे जूझ रहे हैं, तो मुझे एक समाधान मिला ।
एलेक्स डब्ल्यू

7
महत्वपूर्ण नोट :Access-Control-Allow-Originहेडरमें केवल क्रेते डोमेन को अनुमति देने कामतलबयह नहीं है कि अन्य डोमेन इस एंडपॉइंट पर कोई विधि ट्रिगर नहीं कर सकते हैं (उदाहरण के लिए REST API सर्वर)। इसका मतलब यह है कि अस्वीकृत उत्पत्ति परिणाम जावास्क्रिप्ट में उपयोग नहीं कर सकती (ब्राउज़र यह सुनिश्चित करता है)। विशिष्ट डोमेन के लिए किसी समापन बिंदु तक पहुँच को प्रतिबंधित करने के लिए सर्वर-साइड अनुरोध फ़िल्टर का उपयोग करें, जैसे कि अस्वीकृत डोमेन के लिए HTTP 401 लौटाता है।
klues

1
Vary: Originजब आप कई URL का उपयोग करना चाहते हैं, तो आपको हमेशा हेडर को देखना चाहिए: देखिए
Null

जवाबों:


861

ऐसा करने के लिए अनुशंसित तरीके की तरह लगता है कि आपके सर्वर को क्लाइंट से मूल हेडर पढ़ना है, इसकी तुलना उन डोमेन की सूची से करें जिन्हें आप अनुमति देना चाहते हैं, और यदि यह मेल खाता है, तो Originहेडर के मूल्य को क्लाइंट के रूप में वापस गूँजें Access-Control-Allow-Originजवाब में हैडर।

साथ .htaccessआप इसे इस प्रकार कर सकते हैं:

# ----------------------------------------------------------------------
# Allow loading of external fonts
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.example|dev02.otherdomain.example)$" AccessControlAllowOrigin=$0
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header merge Vary Origin
    </IfModule>
</FilesMatch>

41
यह मेल करता है कि W3C क्या सुझाव देता है - w3.org/TR/cors/#access-control-allow-origin-response-hea
सिमोन बी।

153
इस जवाब के साथ मेरी समस्या यह है कि यह वास्तव में मेरी मदद नहीं करता है, क्योंकि हम एक CDN का उपयोग करते हैं, और जाहिर है कि हम यह नियंत्रित नहीं कर सकते कि CDN कैसे प्रोग्रामेटिक रूप से सेट करता है।
बीटी

6
नीचे दिए गए मेरे जवाब में वास्तविक उदाहरण (Nginx) - stackoverflow.com/a/12414239/6084
mjallday

71
यदि कैश या सीडीएन एक चिंता का विषय हैं, तो अलग-अलग मूल हेडर मूल्यों के लिए अलग-अलग प्रतिक्रियाएं रखने के लिए कैश / सीडीएन को बताने के लिए वैरी हेडर का उपयोग करें । आप अपनी प्रतिक्रिया में "वैरी: ओरिजिन" जैसा हेडर शामिल करेंगे। कैश / सीडीएन तब जानता है कि उसे हेडर "उत्पत्ति: foo.example.com " के साथ अनुरोध का एक जवाब भेजना चाहिए , और हेडर "उत्पत्ति: bar.example.com " के अनुरोध के लिए एक अलग प्रतिक्रिया ।
सीन

10
@saturdayplace, यदि आपके पास ओरिजिन हेडर है, तो आप पिछले CORS हैं।
पॉल ड्रेपर

222

एक और समाधान मैं PHP में उपयोग कर रहा हूँ:

$http_origin = $_SERVER['HTTP_ORIGIN'];

if ($http_origin == "http://www.domain1.com" || $http_origin == "http://www.domain2.com" || $http_origin == "http://www.domain3.com")
{  
    header("Access-Control-Allow-Origin: $http_origin");
}

12
क्यों नहीं stackoverflow.com/ में सुझाए गए दृष्टिकोण का उपयोग करें / 1850482/11635 [और न ही एक वाइल्डकार्ड भेजा, मूल अनुरोध]? यह कुछ और अधिक प्राप्त किए बिना सिर्फ अधिक अनुज्ञेय है?
रूबेन बार्टलिंक

15
होने header('Access-Control-Allow-Origin: *')कभी कभी कहते हैं वाइल्ड कार्ड का उपयोग नहीं कर सकते हैं अगर साख झंडा सही है - जब होता है header('Access-Control-Allow-Credentials: true')शायद। इसलिए, $http_originयदि शर्तों को पूरा किया जाता है तो खुद को अनुमति देने के लिए बेहतर है
रकीब

6
अंतिम पंक्ति को बदलने के header("Access-Control-Allow-Origin: " . $http_origin);लिए इसे काम करें
फ्रांस्वा रोमेन

2
यह कोड त्रुटिपूर्ण प्रतीत होता है, जिसमें अगर HTTP_ORIGIN हेडर को मान्यता नहीं दी जाती है, तो स्क्रिप्ट को खुला छोड़कर कोई एक्सेस-कंट्रोल-अनुमति-उत्पत्ति बिल्कुल भी सेट नहीं होती है।
स्टीफन आर

9
@StephenR वास्तव में "वाइड क्लोज्ड" अधिक सटीक होगा, क्योंकि इसका उद्देश्य स्क्रिप्ट को अन्य डोमेन के लिए खोलना है;)
कड़कनाथ

113

यह मेरे लिए काम किया:

SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.example|domain2\.example)$" origin_is=$0 
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is

जब डाल दिया .htaccess, यह सुनिश्चित करने के लिए काम करेंगे।


24
मेरे लिए सबसे अच्छा समाधान है, लेकिन मैंने पोर्ट सपोर्ट (उदाहरण के लिए लोकलहोस्ट: 3000 डेवलपमेंट के लिए) जोड़ा है: SetEnvIf Origin "^ http (s):? // ((। + \।)? (localhost | stackoverflow.com | example1.com) | : [0-9] +)? $ "ओरिजिन_इस = $ ०
१०

2
स्टैकओवरफ़्लो के चारों ओर कई उत्तरों में से, यह वह था जिसने काम किया।
Meetai.com

मुझे Header set Access-Control-Allow-Credentials trueइसके लिए काम करने की आवश्यकता थी जैसे @George का जवाब
99 समस्याएं - सिंटैक्स एक

यह सुनिश्चित करने के लिए काम करता है जब मैं उत्पत्ति का उपयोग करता हूं। लेकिन कुछ मामलों में, उत्पत्ति कुछ अनुरोधों में उपलब्ध नहीं है और यह ब्राउज़र विशिष्ट भी है। फिर, मैंने Refererइसके बजाय उपयोग करने का निर्णय लिया OriginRefererकार्यों का उपयोग करते हुए, लेकिन समस्या यह है Access-Control-Allow-Originकि मैं पूरा URL वापस सेट करता हूं मैं डोमेन नाम को काट देना चाहता हूं Refererऔर इसे असाइन करना चाहता हूं Access-Control-Allow-Origin। इसका परिणाम कुछ इस तरह है - echo http://example.com/index.php/ab/cd | cut -d'/' -f1,2,3बैश कमांड में। क्या यह (अपाचे) कॉन्फिडेंस फाइल में ही संभव है? कोई उपाय?
3AK

1
यह मेरे लिए काम नहीं करता है। जब मैं 2 पंक्तियों को जोड़ता हूं तो हमेशा एक कोड 500 त्रुटि होती है। असल में PHP 5.6.15
BoCyrill

91

मुझे woff- फोंट के साथ एक ही समस्या थी, कई उप-डोमेन का उपयोग करना था। उप-डोमेन की अनुमति देने के लिए मैंने अपने httpd.conf में कुछ इस तरह से जोड़ा:

SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=$1
<FilesMatch "\.woff$">
    Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
</FilesMatch>

कई डोमेन के लिए आप सिर्फ रेगेक्स को बदल सकते हैं SetEnvIf


4
की चाल चली। बस सुनिश्चित करें कि आप नियमित रूप से अभिव्यक्ति को सही ढंग से अपनाते हैं। मैं डोमेन ही है, जैसे की अनुमति के लिए एक प्रश्न चिह्न जोड़ने के लिए की जरूरत (.*\.?example\.org)के लिए example.comऔर sub.example.com
त्रिकोणीय

3
IIS 7 के लिए इसे कैसे अनुकूलित किया जाए, इस पर कोई विचार?
मार्क

हालांकि इस उद्देश्य को हराने नहीं है? एक दुर्भावनापूर्ण उपयोगकर्ता को ओरिजिन हेडर मान को फोर्ज करने से क्या रोकेगा?
ग्रेजोरी जोसेफ

1
@ GrégoryJoseph अभिगम-नियंत्रण-अनुमति-उत्पत्ति किसी ऐसे व्यक्ति से संसाधन छिपाने के बारे में नहीं है जो इसे अनुरोध कर सकता है। यह दुर्भावनापूर्ण साइट को अंत उपयोगकर्ताओं को आपकी साइट पर कॉल करने से रोकने के बारे में है। फ़ॉन्ट फ़ाइलों के मामले में, यह केवल फोंट की हॉट लिंकिंग को प्रभावी रूप से सीमित कर सकता है, क्यों वे (मोज़िला / फ़ायरफ़ॉक्स) अन्य संसाधनों के लिए भी ऐसा नहीं करते थे (जेएस, सीएसएस, आदि) मेरे से परे है।
ट्रैकर 1

@ ट्रेक, आपके रेगेक्स में एक बग है, यह भी अनुमति देगा subexample.com। आपको इसे बदल देना चाहिए:((.*\.)?example\.org)
ब्लूसमून

65

यहां बताया गया है कि यदि ओरिजिनल हेडर वापस गूंजता है यदि यह आपके डोमेन को नग्नेक्स के साथ मेल खाता है, तो यह उपयोगी है यदि आप एक फ़ॉन्ट कई उप-डोमेन को सेवा देना चाहते हैं:

location /fonts {
    # this will echo back the origin header
    if ($http_origin ~ "example.org$") {
        add_header "Access-Control-Allow-Origin" $http_origin;
    }
}

समझ में नहीं आता कि यह कैसे अलग है: add_header एक्सेस-कंट्रोल-अनुमति-उत्पत्ति *; समझाने की परवाह?
Anoyz

यह एक शीर्ष लेख को वापस करने जा रहा है जो ब्राउज़र को केवल निर्दिष्ट डोमेन से अनुरोध भेजने के लिए अधिकृत करता है। अगर मुझे लगता है कि मैं कहूंगा कि ब्राउज़र उस पृष्ठ पर लोड किए गए किसी अन्य डोमेन से सामग्री को प्राधिकृत कर सकता है ताकि सर्वर तक पहुंच हो सके।
mjallday

7
एक बात के लिए @Anoyz सुरक्षा को बढ़ाया जा सकता है जहां "अनुमति दें" की अनुमति नहीं है, लेकिन अनुमति हेडर के कार्यों के लिए एक निर्दिष्ट और मिलान मेजबान नाम है। यहाँ एक उदाहरण, यदि आप प्राधिकरण सूचना क्रॉस डोमेन भेजना चाहते हैं, तो आप "अनुमति *" का उपयोग नहीं कर सकते हैं
TCC

3
है .example.org में किसी भी मूल्य के बाद से यह एक नियमित अभिव्यक्ति के रूप में स्वीकार? किस मामले में, यह गलती से एक कस्टम उदाहरण-ऑर्गन TLD की अनुमति देगा?
अटक गया

1
एक सही regex होना चाहिए "^example\.org$"क्योंकि आप यकीन है कि एक हैकर के साथ अपने regex के माध्यम से पर्ची नहीं कर सकते हैं बनाने की जरूरत है subdomainexample.org(प्रयोग ^) या example.orgevil(प्रयोग $) या examplezorg(भागने \.)
ZEG

27

यहाँ मैं एक PHP अनुप्रयोग के लिए क्या किया है जो AJAX द्वारा अनुरोध किया जा रहा है

$request_headers        = apache_request_headers();
$http_origin            = $request_headers['Origin'];
$allowed_http_origins   = array(
                            "http://myDumbDomain.example"   ,
                            "http://anotherDumbDomain.example"  ,
                            "http://localhost"  ,
                          );
if (in_array($http_origin, $allowed_http_origins)){  
    @header("Access-Control-Allow-Origin: " . $http_origin);
}

यदि मेरे सर्वर द्वारा अनुरोधित उत्पत्ति की अनुमति है, तो वाइल्डकार्ड वापस करने के बजाय हेडर के $http_originमान के रूप में स्वयं को वापस करें ।Access-Control-Allow-Origin*


20

एक नुकसान यह है कि आपको इसके बारे में पता होना चाहिए: जैसे ही आप सीडीएन (या कोई अन्य सर्वर जो स्क्रिप्टिंग की अनुमति नहीं देते हैं) या यदि आपकी फाइलें एक प्रॉक्सी पर कैश की जाती हैं, तो 'ओरिजिन' के आधार पर प्रतिक्रिया बदलकर। अनुरोध शीर्षलेख काम नहीं करेगा।


4
क्या आप इस बारे में विस्तार से बता सकते हैं, या हमें कहीं और बता सकते हैं कि हम अधिक जानकारी की तलाश कर सकते हैं? मैं लाइमलाइट के साथ बस यही करना चाह रहा हूं, और मुझे उम्मीद है कि आप गलत हैं। हमारे एक टेक ऑप्स लोगों ने कहा कि जब तक हमारा सीडीएन सीड सर्वर हेडर भेजता है, सीडीएन खुद भेजेगा। अभी इसका परीक्षण करना बाकी है
बीटी

12
यदि कैश या सीडीएन एक चिंता का विषय हैं, तो अलग-अलग मूल हेडर मूल्यों के लिए अलग-अलग प्रतिक्रियाएं रखने के लिए कैश / सीडीएन को बताने के लिए वैरी हेडर का उपयोग करें। आप अपनी प्रतिक्रिया में "वैरी: ओरिजिन" जैसा हेडर शामिल करेंगे। कैश / सीडीएन तब जानता है कि उसे हेडर "उत्पत्ति: foo.example.com " के साथ अनुरोध का एक जवाब भेजना चाहिए , और हेडर "उत्पत्ति: bar.example.com " के अनुरोध के लिए एक अलग प्रतिक्रिया ।
सीन


20

कई डोमेन के लिए, आपके .htaccess:

<IfModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(www\.)?(domain1.example|domain2.example)$" AccessControlAllowOrigin=$0$1
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header set Access-Control-Allow-Credentials true
</IfModule>

4
यह स्निपेट मेरे लिए पूरी तरह से काम करता है। लेकिन मुझे समझ नहीं आता कि यह क्या करता है: D
कार्ल एडलर

2
यह मेरे लिए काम करता है, हालांकि मुझे एक '^' यानी ... SetEnvIf Origin "^ http (s) ?: // (www \।)
जोड़ना होगा

यह बहुत अधिक stackoverflow.com/a/14034228/209139 के रूप में ही करता है । यह सिर्फ इतना है कि .htaccess सिंटैक्स PHP की तुलना में पढ़ने के लिए बहुत कठिन है। Header set Vary Originइस उत्तर के लिए एक अच्छा अतिरिक्त होगा।
TRIG

1
आपकी मदद के लिए बहुत बहुत धन्यवाद
कूल परफेक्शनिस्ट

2
मैं बदलना पड़ा AccessControlAllowOrigin=$0$1करने के लिए AccessControlAllowOrigin=$0। अन्यथा, यह HTTPS मूल के लिए काम नहीं करता था। http://example.comसही ढंग से बाहर आया, लेकिन अंत में एक अतिरिक्त के साथ, https://example.comबाहर आया । https://example.comss
टीआरजी

17

Nginx उपयोगकर्ताओं के लिए कई डोमेन के लिए CORS की अनुमति देने के लिए। मुझे @ मार्शेल का उदाहरण अच्छा लगता है, हालांकि उनके एवरर्स केवल एक डोमेन से मेल खाते हैं। डोमेन और उपडोमेन की सूची से मेल खाने के लिए इस रेगेक्स से फोंट के साथ काम करना आसान हो जाता है:

location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
   if ( $http_origin ~* (https?://(.+\.)?(domain1|domain2|domain3)\.(?:me|co|com)$) ) {
      add_header "Access-Control-Allow-Origin" "$http_origin";
   }
}

यह केवल "एक्सेस-कंट्रोल-अलाउंस-ओरिजनल" हेडर को इको करेगा जो डोमेन की दी गई सूची से मेल खाता है।


लगता है कि आपको उस regex को \ z के साथ अंत में लॉक करना होगा क्योंकि अन्यथा domain3.com.badhacker.com को अनुमति दी जाएगी।
dft

@ डफ़्ट हम अंत में $ को परिभाषित करते हैं जो ऐसा करता है
एड्रियानो रोजा

क्षमा करें, मेरा उदाहरण उदाहरण के लिए, @AdrianoRosa द्वारा वास्तविक पोस्ट \ z
dft


13

यहाँ yesthatguy से उत्तर के आधार पर, जावा वेब ऐप का एक समाधान है।

मैं जर्सी रेस्ट 1.x का उपयोग कर रहा हूं

जर्सी रेस्ट और कॉर्सस्प्रेसफिल्टर से अवगत होने के लिए web.xml को कॉन्फ़िगर करें

 <!-- Jersey REST config -->
  <servlet>    
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param> 
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
      <param-value>com.your.package.CORSResponseFilter</param-value>
    </init-param>   
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.your.package</param-value>
    </init-param>        
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>

यहाँ CorSResponseFilter का कोड है

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;


public class CORSResponseFilter implements ContainerResponseFilter{

@Override
public ContainerResponse filter(ContainerRequest request,
        ContainerResponse response) {

    String[] allowDomain = {"http://localhost:9000","https://my.domain.example"};
    Set<String> allowedOrigins = new HashSet<String>(Arrays.asList (allowDomain));                  

    String originHeader = request.getHeaderValue("Origin");

    if(allowedOrigins.contains(originHeader)) {
        response.getHttpHeaders().add("Access-Control-Allow-Origin", originHeader);

        response.getHttpHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHttpHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }

    return response;
}

}

उपरोक्त लिंक समाप्त हो गया है, क्या आप नया विवरण जोड़ सकते हैं, या अधिक विवरण के साथ उत्तर अपडेट कर सकते हैं, धन्यवाद
राजकुमार सेमला

मैंने और अधिक विवरण जोड़े हैं, आशा है कि यह मदद करता है
डुओ

12

जैसा कि ऊपर उल्लेख किया गया है, Access-Control-Allow-Originअद्वितीय Varyहोना चाहिए और Originयदि आपको सीडीएन (कंटेंट डिलीवरी नेटवर्क) के पीछे सेट किया जाना चाहिए ।

मेरे Nginx कॉन्फ़िगरेशन का प्रासंगिक भाग:

if ($http_origin ~* (https?://.*\.mydomain.example(:[0-9]+)?)) {
  set $cors "true";
}
if ($cors = "true") {
  add_header 'Access-Control-Allow-Origin' "$http_origin";
  add_header 'X-Frame-Options' "ALLOW FROM $http_origin";
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Vary' 'Origin';
}

है set $corsछिपा हुआ अर्थ किसी तरह का है, या यह सिर्फ अपने conifg के लिए विशिष्ट है? ऐसा लगता है कि इसे दूसरे के साथ एक साथ छोड़ा जा सकता हैif
12

यह सही है, इसे छोड़ दिया जा सकता है यदि यह एकमात्र शर्त है जिसे आप हेडर सेट करने के लिए परीक्षण करते हैं, मेरे पास मेरे कॉन्फ़िगरेशन में कई थे।
१।

9

शायद मैं गलत हूँ, लेकिन जहाँ तक मैं देख सकता हूँ Access-Control-Allow-Originएक "origin-list"पैरामीटर के रूप में है।

द्वारा परिभाषा एक origin-listहै:

origin            = "origin" ":" 1*WSP [ "null" / origin-list ]
origin-list       = serialized-origin *( 1*WSP serialized-origin )
serialized-origin = scheme "://" host [ ":" port ]
                  ; <scheme>, <host>, <port> productions from RFC3986

और इससे, मैं तर्क देता हूं कि विभिन्न मूल भर्ती हैं और अंतरिक्ष को अलग किया जाना चाहिए ।


2
यह युक्ति की सही व्याख्या प्रतीत होती है; उस ने कहा, कल्पना वर्तमान ब्राउज़रों द्वारा पूरी तरह से समर्थित नहीं लगती है (उदाहरण के लिए, मैंने अभी फ़ायरफ़ॉक्स 17.0 पर यह परीक्षण किया है और पुष्टि की है कि यह काम नहीं करेगा)।
रिक रिंसेचे

7
CORS विनिर्देश खंड 5.1 Access-Control-Allow-Origin Response Headerकहा गया है कि मूल-सूची विवश है: बल्कि मूल के एक अंतरिक्ष अलग की गई सूची की इजाजत दी, यह या तो एक मूल या स्ट्रिंग "अशक्त" है।
मैक्सपॉल्क

2
जैसा कि मैंने अपने जवाब में एक टिप्पणी में उल्लेख किया है, यह एक कार्यान्वयनकर्ता नोट का हिस्सा है, न कि RFC 2119 की आवश्यकता। 'सही' उत्तर बिल्कुल अंतरिक्ष-सीमांकित मूल्यों का उपयोग करना है। समस्या बस इतनी है कि कार्यान्वयन अधूरा है और इसलिए 'सही' उत्तर जरूरी नहीं है। यह होना चाहिए, लेकिन यह नहीं है। हालांकि, भविष्य में, जैसा कि कार्यान्वयन बेहतर हो जाते हैं, यह बदल सकता है।
बॉब अमन

8

ExpressJS अनुप्रयोगों के लिए आप उपयोग कर सकते हैं:

app.use((req, res, next) => {
    const corsWhitelist = [
        'https://domain1.example',
        'https://domain2.example',
        'https://domain3.example'
    ];
    if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    }

    next();
});

यह अगले कॉल द्वारा अन्य सभी कॉलों की अनुमति देगा ...
इवगेन नेडा

@ इवनगेना तो? मुद्दा क्या है?
eyecatchUp

7

मैंने HTTPS चलाने वाले एक डोमेन के लिए इसे स्थापित करने के लिए संघर्ष किया, इसलिए मुझे लगा कि मैं समाधान साझा करूंगा। मैंने अपनी httpd.conf फ़ाइल में निम्न निर्देश का उपयोग किया :

    <FilesMatch "\.(ttf|otf|eot|woff)$">
            SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin=$0
            Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </FilesMatch>

example.comअपने डोमेन नाम में परिवर्तन करें। इसे <VirtualHost x.x.x.x:xx>अपने httpd.conf फ़ाइल में जोड़ें । ध्यान दें कि यदि आपका VirtualHostपोर्ट प्रत्यय (जैसे :80) है तो यह निर्देश HTTPS पर लागू नहीं होगा, इसलिए आपको / etc / apache2 / sites-available / default-ssl पर भी जाना होगा और उस फ़ाइल में उसी निर्देश को जोड़ना होगा, अंदर की <VirtualHost _default_:443>धारा।

एक बार कॉन्फिगर फाइल अपडेट हो जाने के बाद, आपको टर्मिनल में निम्नलिखित कमांड्स चलाने होंगे:

a2enmod headers
sudo service apache2 reload

मुझे यह विकल्प पसंद है और इसे @George के कार्यान्वयन के साथ संयोजित / संशोधित किया गया है। कभी-कभी सर्वरों के पास a2enmod उपलब्ध नहीं होता है, इसलिए आपको यह देखने के लिए कि क्या लाइन: LoadModule हेडर_मॉड्यूल मॉड्यूल / mod_headers.so है, को देखने के लिए आपको अपना मुख्य httpd.conf चेक करना होगा।
माइक कोरमेन्डी

मेरे मूल में एक पोर्ट संख्या थी, इसलिए मैंने इसे शामिल करने के लिए नियमित अभिव्यक्ति को संशोधित किया:^http(s)?://(.+\.)?example\.com(:\d+)?$
'21

5

यदि आप फोंट से परेशान हैं, तो उपयोग करें:

<FilesMatch "\.(ttf|ttc|otf|eot|woff)$">
    <IfModule mod_headers>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>
</FilesMatch>

3

एक अधिक लचीला दृष्टिकोण अपाचे 2.4 के भावों का उपयोग करना है। आप डोमेन, रास्तों और हर दूसरे अनुरोध चर के बारे में मेल कर सकते हैं। हालांकि भेजी गई प्रतिक्रिया हमेशा होती है *, केवल प्राप्त करने वाले अनुरोधकर्ता ही होते हैं जो आवश्यकताओं को पूरा करते हैं। Originअभिव्यक्ति में हेडर (या किसी अन्य) अनुरोध हेडर का उपयोग करने से अपाचे को स्वचालित रूप से Varyप्रतिक्रिया हेडर में विलय करने का कारण बनता है , ताकि प्रतिक्रिया एक अलग मूल के लिए पुन: उपयोग नहीं की जाएगी।

<IfModule mod_headers.c>
    <If "%{HTTP:Host} =~ /\\bcdndomain\\.example$/i && %{HTTP:Origin} =~ /\\bmaindomain\\.example$/i">
        Header set Access-Control-Allow-Origin "*"
    </If>
</IfModule>

2
मैं यहाँ आया था क्योंकि कुछ ब्राउज़र *लॉगिन जैसे क्रेडेंशियल्स के साथ स्वीकार नहीं करते हैं । इसलिए बेहतर होगा कि आप इसकी बजाए मैचेड होस्टनाम पास करें *
कीटलडॉग

@KeitelDOG प्रत्येक डोमेन के लिए कोड को दोहराने के बजाय, एक डायनामिक रूप से सही मूल को कैसे कैप्चर करता है और कई मूल होने पर वापस भेज देता है? ऐसा लगता है कि यह अभिव्यक्ति के साथ संभव हो सकता है लेकिन डॉक्स मेरे लिए स्पष्ट नहीं हैं।
वॉल्फ

वास्तव में मेरा असली मुद्दा यह था क्योंकि लारवल ने प्रीफ़लाइट अनुरोध के Access-Control-Allow-Originलिए हेडर वापस नहीं किया था जो हेडर के लिए OPTIONSजांचता है कि क्या सर्वर इस उत्पत्ति की अनुमति देता है। मैंने इसे ठीक करवा दिया। तो *मेरे लिए असली समस्या नहीं थी। लेकिन, फिर भी कुछ ब्राउज़रों को स्वीकार नहीं करते *पहचान के साथ है, इसलिए जब एक वेब एप्लिकेशन पार उत्पत्ति अनुरोध भेज रहा है, वे स्पष्ट करना पड़ता HTTP_ORIGINहैडर कि आप चर के साथ गतिशील रूप का उपयोग हो सकता है Originमें .htaccess, या अपाचे के लिए $_SERVER['HTTP_ORIGIN'];PHP में। वैसे भी आपका समाधान अच्छा है क्योंकि यह सभी मूल की अनुमति देता है, लेकिन कम सुरक्षित है
केइटेलडॉग

लेकिन याद रखने वाली 2 बातें यह है कि 1) प्रदान करना *सब कुछ करने की अनुमति देता है। 2) HOST ORIGIN से अलग है। HOST वास्तविक 'TARGET HOST` है जो हेडर का अनुरोध करने के लिए पारित किया गया है। लेकिन मूल है INITIAL HOSTकि अनुरोध भेजने के लिए है TARGET HOST। इसलिए आपके कोड में, ORIGIN HOSTअनदेखा किया जाता है और कभी उपयोग नहीं किया जाता है। उपरोक्त उत्तर देखें और आप देखेंगे कि वे ORIGINउन्हें जोड़ने के लिए मूल्यों का उपयोग कैसे करते हैं Access-Control-Allow-Origin
कीटलडॉग

@KeitelDOG अभिव्यक्ति *के Originअनुरोध शीर्षलेख का उपयोग करने के कारण सभी को अनुमति नहीं देता है, अपाचे को स्वचालित रूप से Varyप्रतिक्रिया शीर्षक में विलय करने का कारण बनता है , जब तक कि कोई उपयोग नहीं करता req_novary('Origin')(संभावना अवांछनीय)। ब्राउज़रों को पता है कि उन्हें अलग-अलग प्रतिक्रिया मिल सकती है Originऔर यदि भेजा गया मान किसी का परीक्षण पास नहीं करता है, तो Access-Control-Allow-Originहेडर कभी भी सेट नहीं किया जाता है।
वॉलफ

2

HTTP_ORIGIN का उपयोग सभी ब्राउज़रों द्वारा नहीं किया जाता है। HTTP_ORIGIN कितना सुरक्षित है? मेरे लिए यह एफएफ में खाली आता है।
मेरे पास वे साइटें हैं जिनकी मैं अपनी साइट पर पहुंच की अनुमति एक साइट आईडी पर देता हूं, फिर मैं उस आईडी के साथ रिकॉर्ड के लिए अपने DB की जांच करता हूं और SITE_URL कॉलम मान (www.yoursite.com) प्राप्त करता हूं।

header('Access-Control-Allow-Origin: http://'.$row['SITE_URL']);

यहां तक ​​कि अगर एक वैध साइट आईडी पर भेजने का अनुरोध उस साइट आईडी से जुड़े मेरे डीबी में सूचीबद्ध डोमेन से होना चाहिए।


2

यहां अपाचे के लिए एक विस्तारित विकल्प है जिसमें कुछ नवीनतम और नियोजित फ़ॉन्ट परिभाषाएं शामिल हैं:

<FilesMatch "\.(ttf|otf|eot|woff|woff2|sfnt|svg)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "^http(s)?://(.+\.)?(domainname1|domainname2|domainname3)\.(?:com|net|org)$" AccessControlAllowOrigin=$0$1$2
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header set Access-Control-Allow-Credentials true
    </IfModule>
</FilesMatch>

2

ASMX सेवा के लिए कई डोमेन एक्सेस की सुविधा के लिए, मैंने Global.asax फ़ाइल में यह फ़ंक्शन बनाया है:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    string CORSServices = "/account.asmx|/account2.asmx";
    if (CORSServices.IndexOf(HttpContext.Current.Request.Url.AbsolutePath) > -1)
    {
        string allowedDomains = "http://xxx.yyy.example|http://aaa.bbb.example";

        if(allowedDomains.IndexOf(HttpContext.Current.Request.Headers["Origin"]) > -1)
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Headers["Origin"]);

        if(HttpContext.Current.Request.HttpMethod == "OPTIONS")
            HttpContext.Current.Response.End();
    }
}

इस OPTIONSक्रिया के लिए भी CORS से निपटने की अनुमति देता है ।


2

उप-कोड मिलान के लिए PHP कोड उदाहरण।

if( preg_match("/http:\/\/(.*?)\.yourdomain.example/", $_SERVER['HTTP_ORIGIN'], $matches )) {
        $theMatch = $matches[0];
        header('Access-Control-Allow-Origin: ' . $theMatch);
}

2

.NET अनुप्रयोगों के लिए एक काफी आसान कॉपी / पेस्ट के लिए, मैंने इसे एक global.asaxफ़ाइल के भीतर से कॉर्स को सक्षम करने के लिए लिखा था । यह कोड वर्तमान में स्वीकार किए गए उत्तर में दी गई सलाह का पालन करता है, जो प्रतिक्रिया में अनुरोध में दिए गए मूल को दर्शाता है। यह प्रभावी रूप से इसका उपयोग किए बिना '*' प्राप्त करता है।

इसका कारण यह है कि यह AJAX XMLHttpRequest को 'withCredentials' विशेषता के साथ 'true' पर भेजने की क्षमता सहित कई अन्य CORS सुविधाएँ सक्षम करता है

void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.HttpMethod == "OPTIONS")
    {
        Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        Response.AddHeader("Access-Control-Max-Age", "1728000");
        Response.End();
    }
    else
    {
        Response.AddHeader("Access-Control-Allow-Credentials", "true");

        if (Request.Headers["Origin"] != null)
            Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]);
        else
            Response.AddHeader("Access-Control-Allow-Origin" , "*");
    }
}

2

PHP कोड:

$httpOrigin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : null;
if (in_array($httpOrigin, [
    'http://localhost:9000', // Co-worker dev-server
    'http://127.0.0.1:9001', // My dev-server
])) header("Access-Control-Allow-Origin: ${httpOrigin}");
header('Access-Control-Allow-Credentials: true');

1

और एक और जवाब Django में। एक ही दृश्य को कई डोमेन से CORS की अनुमति दें, यहां मेरा कोड है:

def my_view(request):
    if 'HTTP_ORIGIN' in request.META.keys() and request.META['HTTP_ORIGIN'] in ['http://allowed-unsecure-domain.com', 'https://allowed-secure-domain.com', ...]:
        response = my_view_response() # Create your desired response data: JsonResponse, HttpResponse...
        # Then add CORS headers for access from delivery
        response["Access-Control-Allow-Origin"] = request.META['HTTP_ORIGIN']
        response["Access-Control-Allow-Methods"] = "GET" # "GET, POST, PUT, DELETE, OPTIONS, HEAD"
        response["Access-Control-Max-Age"] = "1000"  
        response["Access-Control-Allow-Headers"] = "*"  
        return response

1

AWS लाम्बा / एपीआई गेटवे

सर्वरलेस AWS लैम्ब्डा और एपीआई गेटवे पर कई मूल को कॉन्फ़िगर करने के तरीके के बारे में जानकारी के लिए - कुछ के लिए एक बड़े समाधान के बावजूद, जो एक को लगता है कि काफी सीधा होना चाहिए - यहां देखें:

https://stackoverflow.com/a/41708323/1624933


एपीआई गेटवे में कई मूल को कॉन्फ़िगर करना वर्तमान में संभव नहीं है, यहां देखें: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html ), लेकिन सिफारिश ( उपरोक्त उत्तर) है:

  • ब्राउज़र द्वारा भेजे गए ओरिजिन हेडर का निरीक्षण करें
  • मूल के एक श्वेतसूची के खिलाफ इसकी जाँच करें
  • यदि यह मेल खाता है, तो आने वाले ओरिजिनल को एक्सेस-कंट्रोल-अलाउंस-ओरिजिन हेडर के रूप में लौटाएं, अन्यथा एक प्लेसहोल्डर (डिफ़ॉल्ट ओरिजिन) लौटाएं।

सरल समाधान स्पष्ट रूप से सभी (*) को सक्षम कर रहा है:

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
        },
        body: JSON.stringify([{

लेकिन एपीआई गेटवे साइड (ऊपर दूसरा लिंक देखें) पर ऐसा करना बेहतर हो सकता है।


2
Access-Control-Allow-Credentials: trueवाइल्डकार्ड के साथ अनुमति नहीं है Access-Control-Allow-Origin: *<origin>इसके बजाय एक विशिष्ट सेट करें ।
टॉम

@ टॉम, हाँ, यह सुनिश्चित नहीं था कि वहाँ क्यों था, मुझे याद नहीं आ रहा है, लेकिन मैंने इसे एडब्ल्यूएस में जोड़े गए चूक से कॉपी किया होगा? हालांकि यह इंगित करने के लिए धन्यवाद।
तैमुक

0

SSL पर विज्ञापन देने और RFC में व्याकरण के बारे में Google के समर्थन के जवाब से ही ऐसा प्रतीत होता है कि आप URL का परिसीमन कर सकते हैं। यह निश्चित नहीं है कि विभिन्न ब्राउज़रों में यह कितना अच्छा है।


'ssl पर विज्ञापन परोसना ' कड़ियों के लिंक w3.org/TR/cors/#access-control-allow-origin-response-header में एक नोट है, जो कहता है, "व्यवहार में मूल-सूची या अशक्त उत्पादन अधिक विवश है। । मूल के एक अंतरिक्ष अलग की गई सूची की इजाजत दी बजाय, यह या तो एक मूल या स्ट्रिंग "अशक्त" है।
spazm

हालांकि उस विवरण पर ध्यान देना महत्वपूर्ण है, जब एक विनिर्देश "व्यवहार में" कहता है, इसका मतलब यह नहीं है कि यह केवल उस तरह से करने के लिए वैध है। इसका मतलब है कि यदि आप इसे इस तरह करते हैं, तो आप समस्याओं में भाग सकते हैं क्योंकि अधिकांश कार्यान्वयनकर्ता या तो गलत तरीके से या अपूर्ण रूप से कल्पना को लागू करते हैं। स्पेसिफ़िकेशन अंतरिक्ष की एक अलग-अलग सूची की अनुमति देता है, जिसे आप यहाँ EBNF में देख सकते हैं origin-list: tools.ietf.org/html/rfc6454#section-7.1
बॉब अमन

0

यदि आप कॉर्स का उपयोग करके इसे काम करने के लिए मेरे जैसे कई कोड उदाहरणों की कोशिश करते हैं, तो यह उल्लेख के लायक है कि आपको अपना कैश पहले साफ़ करने की कोशिश करनी है कि क्या यह वास्तव में काम करता है, पुराने मुद्दों जैसे कि अभी भी मौजूद है, भले ही यह मौजूद हो सर्वर पर हटा दिया गया (क्योंकि यह अभी भी आपके कैश में सहेजा गया है)।

CTRL + SHIFT + DELअपने कैश को हटाने के लिए Google Chrome में उदाहरण के लिए ।

इसने कई शुद्ध .htaccessसमाधानों की कोशिश करने के बाद इस कोड का उपयोग करने में मेरी मदद की और यह केवल एक ही काम कर रहा था (कम से कम मेरे लिए):

    Header add Access-Control-Allow-Origin "http://google.com"
    Header add Access-Control-Allow-Headers "authorization, origin, user-token, x-requested-with, content-type"
    Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

    <FilesMatch "\.(ttf|otf|eot|woff)$">
        <IfModule mod_headers.c>
            SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.com|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0
            Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        </IfModule>
    </FilesMatch>

यह भी ध्यान दें कि यह व्यापक रूप से फैला हुआ है कि कई समाधान कहते हैं कि आपको टाइप करना है Header set ...लेकिन यह है Header add ...। आशा है कि यह मेरी तरह अब कुछ घंटों के लिए किसी को परेशान करने में मदद करता है।


0

नीचे उत्तर C # के लिए विशिष्ट है, लेकिन अवधारणा सभी विभिन्न प्लेटफार्मों पर लागू होनी चाहिए।

एक वेब एपीआई से क्रॉस ओरिजिनल रिक्वेस्ट को अनुमति देने के लिए, आपको अपने एप्लिकेशन में ऑप्शन रिक्वेस्ट को अनुमति देने की जरूरत है और कंट्रोलर स्तर पर एनोटेशन नीचे जोड़ें।

[EnableCors (UrlString, Header, Method)] अब मूल केवल स्ट्रिंग के रूप में पारित किया जा सकता है। यदि आप अनुरोध में एक से अधिक URL पास करना चाहते हैं तो इसे अल्पविराम से अलग मान के रूप में पास करें।

UrlString = " https: //a.hello.com,https: //b.hello.com "


0

Access-Control-Allow-Origin हेडर के लिए केवल एक ही मूल निर्दिष्ट किया जा सकता है। लेकिन आप अनुरोध के अनुसार अपनी प्रतिक्रिया में मूल सेट कर सकते हैं। इसके अलावा वैरी हेडर सेट करना न भूलें। PHP में मैं निम्नलिखित कार्य करूँगा:

    /**
     * Enable CORS for the passed origins.
     * Adds the Access-Control-Allow-Origin header to the response with the origin that matched the one in the request.
     * @param array $origins
     * @return string|null returns the matched origin or null
     */
    function allowOrigins($origins)
    {
        $val = $_SERVER['HTTP_ORIGIN'] ?? null;
        if (in_array($val, $origins, true)) {
            header('Access-Control-Allow-Origin: '.$val);
            header('Vary: Origin');

            return $val;
        }

        return null;
    }

  if (allowOrigins(['http://localhost', 'https://localhost'])) {
      echo your response here, e.g. token
  }

-2

हम इसे Asp.net एप्लिकेशन के लिए Global.asax फ़ाइल में भी सेट कर सकते हैं।

protected void Application_BeginRequest(object sender, EventArgs e)
    {

    // enable CORS
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "https://www.youtube.com");

    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.