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 일치 부분을 수정하여 제어 할 수 있습니다.
허용 된 답변 은 기본 도메인과 일치 할 수 없으며 하위 도메인에서만 작동하기 때문에이 질문에 대답하고 있습니다. 또한 정규식 그룹화는 성능 적중 이므로 필요하지 않습니다.
예를 들어 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
(이 답변을 수락 된 답변에 대한 의견으로 남기려고했지만 아직 그렇게 할 수는 없습니다)
원래 답변은 Apache 2.4 이전의 답변이었습니다. 그것은 나를 위해 작동하지 않았다. 다음은 2.4에서 작동하도록 변경 한 내용입니다. 이것은 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"
고아 가 정규식으로 끝나서 실제 호스트 (프로토콜 또는 포트에주의를 기울이지 않음) 만 비교 하기 위해 Lars의 답변을 약간 수정 \
해야했으며 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']));
}
들어 봄 부팅 나는이 발견 RegexCorsConfiguration
공식을 확장하는을 CorsConfiguration
: https://github.com/looorent/spring-security-jwt/blob/master/src/main/java/be/looorent/security/jwt/RegexCorsConfiguration.java
Lars의 답변이 약간 변경되었습니다.
<?php
function validateOrigin($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;
}
// CORS Preflight
if($_SERVER['REQUEST_METHOD'] === 'OPTIONS')
{
header('Access-Control-Allow-Origin: '.validateOrigin('https://*.domain.com', $_SERVER['HTTP_ORIGIN']));
header('X-Response-Code: 204', true, 204);
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Headers: Content-Type');
} elseif($_SERVER['REQUEST_METHOD'] === 'GET'
&& isset($_GET['VARIABLEHERE'])
) {
// CODE HERE
if($info["http_code"] === 200){
// 200 OK
header('Content-type: application/json; charset=utf-8');
// CORS headers
header('Access-Control-Allow-Origin: '.validateOrigin('https://*.domain.com', $_SERVER['HTTP_ORIGIN']));
echo $response;
} else {
header('X-Service-Response-Code: '.$info["http_code"], true, $info["http_code"]);
}
} else {
// 400 bad request.
header('X-Response-Code: 400', true, 400);
}
exit;
'Programing' 카테고리의 다른 글
"호출 가능"이란 무엇입니까? (0) | 2020.03.23 |
---|---|
JSON에서 큰 따옴표를 이스케이프 처리하는 방법 (0) | 2020.03.23 |
vim 줄 번호-기본적으로 어떻게 설정합니까? (0) | 2020.03.23 |
parseInt가 Array # map으로 NaN을 생성하는 이유는 무엇입니까? (0) | 2020.03.23 |
저장 프로 시저 란 무엇입니까? (0) | 2020.03.23 |