我正在尝试为所有子域,端口和协议启用CORS。
例如,我希望能够从http://sub.mywebsite.example:8080/到https://www.mywebsite.example/*运行XHR请求
通常情况下,我想启用来自源匹配的请求(并且仅限于):
/ / * .mywebsite.example: * / *
我正在尝试为所有子域,端口和协议启用CORS。
例如,我希望能够从http://sub.mywebsite.example:8080/到https://www.mywebsite.example/*运行XHR请求
通常情况下,我想启用来自源匹配的请求(并且仅限于):
/ / * .mywebsite.example: * / *
当前回答
对于Spring,你应该使用allowedOriginPatterns,它完全是你想要的
setAllowedOrigins(java.util.List<java.lang.String>)的替代方案,除了端口列表外,还支持在主机名中的任何位置使用“*”的更灵活的起源模式。例子:
https://*.domain1.com -- domains ending with domain1.com
https://*.domain1.com:[8080,8081] -- domains ending with domain1.com on port 8080 or port 8081
https://*.domain1.com:[*] -- domains ending with domain1.com on any port, including the default port
与只支持""而不能与allowCredentials一起使用的allowedOrigins相反,当一个allowedOriginPattern被匹配时,Access-Control-Allow-Origin响应头被设置为匹配的原点,而不是""或模式。因此,allowedOriginPatterns可以与setAllowCredentials(java.lang.Boolean)设置为true结合使用。
例如:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
List<String> allowedOrigins = List.of("https://*.example.com", "http://*.example2.com[80,8080]");
registry.addMapping("/**").allowedOriginPatterns(allowedOrigins.toArray(new String[0]));
}
};
}
其他回答
在我的例子中使用的是angular
在我的HTTP拦截器,我设置
with Credentials: true.
在请求头中
我需要一个只有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'),
对于Spring,你应该使用allowedOriginPatterns,它完全是你想要的
setAllowedOrigins(java.util.List<java.lang.String>)的替代方案,除了端口列表外,还支持在主机名中的任何位置使用“*”的更灵活的起源模式。例子:
https://*.domain1.com -- domains ending with domain1.com
https://*.domain1.com:[8080,8081] -- domains ending with domain1.com on port 8080 or port 8081
https://*.domain1.com:[*] -- domains ending with domain1.com on any port, including the default port
与只支持""而不能与allowCredentials一起使用的allowedOrigins相反,当一个allowedOriginPattern被匹配时,Access-Control-Allow-Origin响应头被设置为匹配的原点,而不是""或模式。因此,allowedOriginPatterns可以与setAllowCredentials(java.lang.Boolean)设置为true结合使用。
例如:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
List<String> allowedOrigins = List.of("https://*.example.com", "http://*.example2.com[80,8080]");
registry.addMapping("/**").allowedOriginPatterns(allowedOrigins.toArray(new String[0]));
}
};
}
对我来说,我想要一个多域选项,这就是我使用的解决方案,使用python和flask,
VALID_DOMAINS = 'https://subdomain1.example.com', 'https://subdomain2.example.com'
def handle_request(request):
origin = request.headers.get('Origin')
if request.method == 'OPTIONS':
if origin not in :
return ''
headers = {
'Access-Control-Allow-Origin': origin,
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '3600',
}
return '', 204, headers
return (
main_function_with_logic(request),
200,
{'Access-Control-Allow-Origin': origin,
...}
)
显然,您可以将VALID_DOMAINS扩展到任意您想要的长度,以及任何您想要的(非https、不同端口等),并在请求上进行检查。
与通配符解决方案相比,我更喜欢这种解决方案,因此这是我在运行的服务器上的选择。
我不得不稍微修改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']));
}