[cors] Access-Control-Allow-Origin 와일드 카드 하위 도메인, 포트 및 프로토콜

모든 하위 도메인, 포트 및 프로토콜에 CORS를 사용하려고합니다.

예를 들어 http://sub.mywebsite.com:8080/ 에서 https://www.mywebsite.com/으로 XHR 요청을 실행할 수 있기를 원합니다. *

일반적으로 원점 일치 요청을 활성화하고 싶습니다 (및 제한).

//*.mywebsite.com:*/*



답변

DaveRandom의 답변을 바탕으로 , 나는 또한 Access-Control-Allow-Origin재 작성 규칙을 사용하지 않고 동일한 결과 ( 현재 특정 프로토콜 + 도메인 + 포트로 동적으로 설정 됨)를 생성하는 약간 더 간단한 Apache 솔루션을 발견했습니다 .

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"

그리고 그게 다야.

모든 하위 도메인 외에 상위 도메인 (예 : mywebsite.com)에서 CORS를 활성화하려는 사용자는 첫 번째 줄의 정규 표현식을 다음과 같이 간단히 바꿀 수 있습니다.

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

참고 : 사양 준수 및 올바른 캐싱 동작을 Vary: Origin위해 비 CORS 요청 및 허용되지 않은 출처의 요청에 대해서도 CORS 지원 리소스에 대한 응답 헤더를 항상 추가 하십시오 ( 예제 참조 ).


답변

CORS 사양은 전부 또는 아무것도 아닙니다. 그것은 단지 지원 *, null또는 정확한 프로토콜 + 도메인 + 포트 : http://www.w3.org/TR/cors/#access-control-allow-origin-response-header

서버는 정규식을 사용하여 오리진 헤더의 유효성을 검사해야하며 Access-Control-Allow-Origin 응답 헤더에서 오리진 값을 에코 할 수 있습니다.


답변

편집 : 이 대신 @Noyo의 솔루션을 사용하십시오 . 로드시 더 단순하고 명확하며 성능이 훨씬 뛰어납니다.

역사적 목적만을위한 오리지널 답변 왼쪽.


나는이 문제를 해결하고 Apache와 작동하는 재사용 가능한 .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는 AS ACCESS_CONTROL_ROOT그것은에 기원을 제한합니다 sub.mydomain.com*.sub.mydomain.com(도메인 루트가 될 필요가 없습니다 그것을 즉). 변경 가능한 요소 (프로토콜, 포트)는 정규식의 URI 일치 부분을 수정하여 제어 할 수 있습니다.


답변

허용 된 답변을 따라갈 수 없기 때문에이 질문에 대답하고 있습니다.

  1. 정규식 그룹화는 성능 적중 이며 필요하지 않습니다.
  2. 기본 도메인과 일치 할 수 없으며 하위 도메인에서만 작동합니다.

예를 들어 http://mywebsite.com에 CORS 헤더를 보내지 않지만 http://somedomain.mywebsite.com/에 대해서는 작동합니다 .

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"

사이트를 활성화하려면 위의 Apache 구성에서 “mywebsite.com”대신 사이트를 배치하면됩니다.

여러 사이트를 허용하려면

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

배포 후 테스트 :

다음 컬 응답에는 변경 후 “Access-Control-Allow-Origin”헤더가 있어야합니다.

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


답변

PHP 전용 솔루션이 필요했기 때문에 누군가가 필요로하는 경우를 대비하여. “* .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'),


답변

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, 아무도 일하지 키워드가 오래된 또는 유효하지 않은 경우 내가 아무 생각이 없지만, SO에 많은 답변에 제안 의 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]


답변

“쿠키 도메인”(www.domain.tld)에서 글꼴을 읽을 때 정적 “쿠키가없는”도메인에서 Font Awesome과 비슷한 문제가 발생했으며이 게시물이 우리의 영웅이었습니다. 여기를 참조하십시오 : 어떻게 ‘누락 간 리소스 공유 (CORS) 응답 헤더’webfont 문제를 해결할 수 있습니까?

copy / paste-r 유형 (및 소품을 제공하기 위해)에 대해서는 모든 기부금에서 이것을 모아서 사이트 루트의 .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>

매우 안전하고 우아합니다. 그것을 좋아하십시오 : 당신은 자원 도둑 / 핫 링크 유형의 서버 대역폭을 열 필요가 없습니다.

소품 : @Noyo @DaveRandom @ pratap-koritala

(이 답변을 수락 된 답변에 대한 의견으로 남기려고했지만 아직 그렇게 할 수는 없습니다)