문제

여러 크로스 도메인을 사용하는 방법이 있습니까? Access-Control-Allow-Origin 헤더?

나는 알고있다 *, 그러나 너무 개방적입니다. 나는 정말로 몇 개의 도메인 만 허용하고 싶습니다.

예를 들어, 다음과 같은 것 :

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

위의 코드를 시도했지만 Firefox에서는 작동하지 않는 것 같습니다.

여러 도메인을 지정할 수 있습니까? 아니면 하나만 붙어 있습니까?

도움이 되었습니까?

해결책

권장되는 방법은 서버에서 클라이언트에서 원점 헤더를 읽고 허용하려는 도메인 목록과 비교하고 일치하는 경우 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>

다른 팁

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");
}

이것은 나를 위해 효과가있었습니다.

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, 그것은 확실히 작동 할 것입니다.

나는 Woff-Fonts와 같은 문제가 있었고, 여러 하위 도메인에 액세스해야했습니다. 하위 도메인을 허용하기 위해 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>

여러 도메인의 경우 REGEX를 변경할 수 있습니다. SetEnvIf.

다음은 Nginx와 도메인과 일치하는 경우 Origin 헤더를 반영하는 방법은 다음과 같습니다. 글꼴 다중 하위 도메인을 제공하려는 경우 유용합니다.

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

다음은 Ajax가 요청하는 PHP 신청서에 대해 한 일입니다.

$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 반환하는 대신 헤더 * 와일드 카드.

알아야 할 단점이 있습니다. CDN (또는 스크립팅을 허용하지 않는 다른 서버)에 파일을 아웃소싱하자마자 파일이 프록시에 캐시되면 '원산지'에 따라 응답을 변경하십시오. 요청 헤더는 작동하지 않습니다.

여러 도메인의 경우 .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>

NGINX 사용자가 여러 도메인의 CORS를 허용합니다. 그의 Anwers는 하나의 도메인과 일치하지만 @Marshall의 예제를 좋아합니다. 도메인 및 하위 도메인 목록을 일치시키기 위해이 REGEX는 글꼴로 쉽게 작업 할 수 있도록합니다.

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";
   }
}

이것은 주어진 도메인 목록과 일치하는 "액세스-제어-홀로-오리핀"헤더 만 반향합니다.

URL 재 작성 2.0 모듈이 설치된 IIS 7.5+의 경우 이렇게 대답합니다

다음은 Yesthatguy의 답변을 기반으로 Java Web App의 솔루션입니다.

나는 Jersey Rest 1.x를 사용하고 있습니다

Jersey Rest 및 CorsresponseFilter를 알기 위해 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;
}

}

앞에서 말했다시피, Access-Control-Allow-Origin 독특하고 Vary 설정해야합니다 Origin CDN 뒤에있는 경우 (콘텐츠 전달 네트워크).

내 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';
}

어쩌면 내가 틀렸을 수도 있지만 내가 볼 수있는 한 Access-Control-Allow-Origin 있습니다 "origin-list" 매개 변수로.

에 의해 정의 an 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

그리고 이것으로부터, 나는 다른 기원이 인정되고 분리 된 공간.

나는 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-avable/default-ssl 해당 파일에 동일한 지침을 추가하십시오. <VirtualHost _default_:443> 부분.

구성 파일이 업데이트되면 터미널에서 다음 명령을 실행해야합니다.

a2enmod headers
sudo service apache2 reload

글꼴에 문제가있는 경우 사용하십시오.

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

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();
});

http_origin은 모든 브라우저에서 사용되지 않습니다. http_origin은 얼마나 안전합니까? 나를 위해 그것은 ff에서 비어 있습니다.
내 사이트에 액세스 할 수있는 사이트가 사이트 ID를 통해 전송 한 다음 해당 ID로 레코드를 확인하고 Site_url 열 값 (www.yoursite.com)을 얻습니다.

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

유효한 사이트 ID로 보내더라도 해당 사이트 ID와 관련된 DB에 나열된 도메인에서 요청이 필요합니다.

다음은 최신 및 계획된 글꼴 정의를 포함하는 Apache의 확장 옵션입니다.

<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>

그리고 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

.NET 애플리케이션에 대해 상당히 쉬운 복사 / 붙여 넣기를 위해 Global.asax 파일 내에서 CORS를 활성화하기 위해 이것을 작성했습니다. 이 코드는 현재 인정 된 답변에 주어진 조언을 따릅니다. 요청에 응답에 대한 원산지가 주어진 모든 것을 반영합니다. 이것은 사용하지 않고 효과적으로 '*'를 달성합니다. 그 이유는 'withedentials'속성으로 'true'로 설정된 Ajax xmlhttprequest를 보내는 기능을 포함하여 여러 다른 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" , "*");
    }
}

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();
    }
}

이것은 CORS 처리가 가능합니다 OPTIONS 동사도.

서브 도메인 매칭을위한 PHP 코드 예제.

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

보다 유연한 접근 방식은 Apache 2.4의 표현을 사용하는 것입니다. 도메인, 경로 및 거의 모든 다른 요청 변수와 일치 할 수 있습니다. 반응은 있지만 * 대체로, 그 응답을받는 유일한 요청자는 어쨌든 요구 사항을 충족하는 요청입니다.

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

Google의 지원 답변 SSL에 대한 광고 제공 그리고 RFC 자체의 문법 URL을 공간으로 구분할 수 있음을 나타냅니다. 이것이 다른 브라우저에 얼마나 잘 지원되었는지 잘 모르겠습니다.

CORS를 사용하여 작동하기 위해 나와 같은 많은 코드 예제를 시도한다면, 실제로 작동하는 경우 캐시를 먼저 시도해야합니다. 이전 이미지가 여전히 존재하는 경우와 같은 문제와 비슷한 경우에도 Cache를 먼저 시도해야합니다. 서버에서 삭제되었습니다 (캐시에 여전히 저장되어 있기 때문에).

예를 들어 Ctrl + Shift + Del Google 크롬에서 캐시를 삭제합니다.

이것은 많은 순수한 시도 후이 코드를 사용하는 데 도움이되었습니다. .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 .... 이것이 나처럼 몇 시간 동안 같은 문제를 겪는 사람이 도움이되기를 바랍니다.

아래 답변은 C#에만 해당되지만 개념은 모든 다른 플랫폼에 적용 할 수 있어야합니다.

웹 API에서 Cross Origin 요청을 허용하려면 응용 프로그램에 옵션 요청을 허용하고 컨트롤러 수준에서 아래 주석을 추가해야합니다.

enablecors (urlstring, header, method)] 이제 원점은 문자열로만 전달 될 수 있습니다. 따라서 요청에서 둘 이상의 URL을 전달하려면 쉼표 분리 된 값으로 전달하십시오.

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

액세스-제어-홀로-오리핀 헤더에 대해서만 단일 원점 만 지정할 수 있습니다. 그러나 요청에 따라 응답에서 원점을 설정할 수 있습니다. 또한 Vary 헤더를 설정하는 것을 잊지 마십시오. 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
  }

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");

    }

대답은 헤더를 두 번 이상 사용하는 것 같습니다. 그것은 보내기보다는 대신입니다

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

보내다

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

Apache에서는이 작업을 수행 할 수 있습니다 httpd.conf <VirtualHost> 섹션 또는 .htaccess 파일 사용 mod_headers 그리고이 구문 :

Header add Access-Control-Allow-Origin "http://domain1.example"
Header add Access-Control-Allow-Origin "http://domain2.example"
Header add Access-Control-Allow-Origin "http://domain3.example"

속임수는 사용하는 것입니다 add 보다는 append 첫 번째 논쟁으로.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top