Access-Control-Allow-Origin通配符子域,端口和协议

本文介绍了如何配置CORS以允许来自所有子域、端口和协议的请求。通过修改Apache的.htaccess或httpd.conf文件,使用正则表达式验证源标头,实现Access-Control-Allow-Origin响应头的动态设置。同时,文章提醒了为确保合规性和正确缓存,始终需要为CORS资源添加Vary响应头。
摘要由CSDN通过智能技术生成

本文翻译自:Access-Control-Allow-Origin wildcard subdomains, ports and protocols

I'm trying to enable CORS for all subdomains, ports and protocol. 我正在尝试为所有子域,端口和协议启用CORS。

For example, I want to be able to run an XHR request from http://sub.mywebsite.com:8080/ to https://www.mywebsite.com/ * 例如,我希望能够运行从http://sub.mywebsite.com:8080/https://www.mywebsite.com/的XHR请求*

Typically, I'd like to enable request from origins matching (and limited to): 通常,我想启用来自匹配(并限于)的来源的请求:

//*.mywebsite.com:*/*


#1楼

参考:https://stackoom.com/question/WKUc/Access-Control-Allow-Origin通配符子域-端口和协议


#2楼

The CORS spec is all-or-nothing. CORS规格全有或全无。 It only supports * , null or the exact protocol + domain + port: http://www.w3.org/TR/cors/#access-control-allow-origin-response-header 它仅支持*null或确切的协议+域+端口: http : //www.w3.org/TR/cors/#access-control-allow-origin-response-header

Your server will need to validate the origin header using the regex, and then you can echo the origin value in the Access-Control-Allow-Origin response header. 您的服务器将需要使用正则表达式验证原始标头,然后可以在Access-Control-Allow-Origin响应标头中回显原始值。


#3楼

EDIT : Use @Noyo's solution instead of this one. 编辑 :使用@ Noyo的解决方案,而不是此解决方案 It's simpler, clearer and likely a lot more performant under load. 它在负载下更简单,更清晰,并且性能可能更高。

ORIGINAL ANSWER LEFT HERE FOR HISTORICAL PURPOSES ONLY!! 原始答案仅用于历史目的!!


I did some playing around with this issue and came up with this reusable .htaccess (or httpd.conf) solution that works with Apache: 我对此问题做了一些尝试,并提出了与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>

Just set the ACCESS_CONTROL_ROOT variable at the top of the block to your root domain and it will echo the Origin: request header value back to the client in the Access-Control-Allow-Origin: response header value if it matches your domain. 只需将块顶部的ACCESS_CONTROL_ROOT变量设置为您的根域,如果它与您的域匹配,它将在Access-Control-Allow-Origin:响应头值中将Origin:请求标头值回显给客户端。

Note also that you can use sub.mydomain.com as the ACCESS_CONTROL_ROOT and it will limit origins to sub.mydomain.com and *.sub.mydomain.com (ie it doesn't have to be the domain root). 另请注意,您可以将sub.mydomain.com用作ACCESS_CONTROL_ROOT ,它将源限制为sub.mydomain.com*.sub.mydomain.com (即它不必是域根)。 The elements that are allowed to vary (protocol, port) can be controlled by modifying the URI matching portion of the regex. 可以通过修改正则表达式的URI匹配部分来控制允许更改的元素(协议,端口)。


#4楼

Based on DaveRandom's answer , I was also playing around and found a slightly simpler Apache solution that produces the same result ( Access-Control-Allow-Origin is set to the current specific protocol + domain + port dynamically) without using any rewrite rules: 根据DaveRandom的回答 ,我还在玩耍,发现了一个稍简单的Apache解决方案,它可以产生相同的结果(将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"

And that's it. 就是这样。

Those who want to enable CORS on the parent domain (eg mywebsite.com) in addition to all its subdomains can simply replace the regular expression in the first line with this one: 那些除了其所有子域之外还希望在父域(例如mywebsite.com)上启用CORS的用户,可以简单地用以下内容替换第一行中的正则表达式:

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

Note: For spec compliance and correct caching behavior, ALWAYS add the Vary: Origin response header for CORS-enabled resources, even for non-CORS requests and those from a disallowed origin (see example why ). 注意:为了符合规范和正确的缓存行为,请始终为启用了CORS的资源添加Vary: Origin响应标头,即使对于非CORS请求和来自不允许的原始请求(请参见示例 )。


#5楼

I needed a PHP-only solution, so just in case someone needs it as well. 我需要一个仅PHP的解决方案,以防万一有人需要它。 It takes an allowed input string like "*.example.com" and returns the request header server name, if the input matches. 它接受一个允许的输入字符串,例如“ * .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;
}

And here are the test cases for a phpunit data provider: 以下是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'),

#6楼

I'm answering this question, because the accepted answer can't match primary domain and only works for sub domain. 我正在回答这个问题,因为接受的答案无法匹配主域,仅适用于子域。 Also, regex grouping is a performance hit , which is not necessary. 同样, 正则表达式分组也不会对性能造成影响

For example: It won't send CORS headers for http://mywebsite.com while works for http://somedomain.mywebsite.com/ 例如:它不会为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"

To enable for your site, you just put your site in place of "mywebsite.com" in the above Apache Configuration. 要启用您的站点,只需在上面的Apache配置中将站点替换为“ mywebsite.com”即可。

To allow Multiple sites: 要允许多个站点:

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

Testing After deploying: 部署后的测试:

The following curl response should have the "Access-Control-Allow-Origin" header after the change. 更改后,以下卷曲响应应具有“ Access-Control-Allow-Origin”标头。

curl -X GET -H "Origin: http://examplesite1.com" --verbose http://examplesite2.com/query
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值