设置带通配符子域名的Access-Control-Allow-Origin实现安全跨域资源共享

互联网资源共享

在现代互联网技术中,跨域资源共享(CORS:Cross-Origin Resource Sharing)机制使用非常广泛,在兼顾安全性的基础上解决了跨域消息互通,资源共享的问题,目前绝大多数主流的浏览器均支持跨域资源共享(CORS)。然而,按跨域资源共享(CORS)的配置说明,参数Access-Control-Allow-Origin的值要么是通配符(*),要么是指定的固定域名。前者太过开放,不安全,而后者又太死板,不灵活。如果能设置带通配符子域名的Access-Control-Allow-Origin参数那就好了。本文小卓将以NGINX为例设置带通配符子域名的Access-Control-Allow-Origin实现安全跨域资源共享

什么是跨域资源共享(CORS:Cross-Origin Resource Sharing)?

说起跨域资源共享(CORS:Cross-Origin Resource Sharing)就不得不提到浏览器的同源策略了,即:基于安全的理由,不同域的客户端脚本不能读写对方的资源,先更了解更多同源策略,可以阅读同源策略(Same-origin Policy)。但是实践中有一些场景需要跨域的读写。为了提供满足实际需要,在XMLHttpRequest v2标准下,跨域资源共享(CORS)的策略被提出,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求,允许网页从不同的域访问其资源。简而言之,跨域资源共享(CORS:Cross-Origin Resource Sharing)就是为了实现可控的跨域访问而生的。

如何设置跨域资源共享(CORS:CROSS-ORIGIN RESOURCE SHARING)?

正如前文所述,目前绝大多数主流的浏览器均已支持跨域资源共享(CORS),这里的设置指的是服务器端的设置。跨域资源共享(CORS)通过在服务器端设置多个控制参数来完成,这些控制参数在响应浏览器端的请求时,会以header的形势通过响应消息带回带浏览器端,这些参数主要是下面这么四个:

  1. Access-Control-Allow-Origin: http://foo.example
  2. Access-Control-Allow-Methods: POST, GET, OPTIONS
  3. Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
  4. Access-Control-Max-Age: 86400

这些基本参数的基本设置方式不是本文的重点,需要了解的朋友请阅读《HTTP访问控制:CORS》,这里需要重点指出的是参数Access-Control-Allow-Origin,通过配置Access-Control-Allow-Origin参数可以指定哪些域可以访问你的服务器。你也可以设置简单的通配符(*),但是如果你正允许Cockie共享的话,你不得不一个个指定额外的域名,因为简单的通配符(*)就不行了。所以你会想要能设置像“*.yourdomain.com”这样含有通配符的子域名。按照Access-Control-Allow-Origin设置的说明,Access-Control-Allow-Origin参数只接受下面两种值,含有通配符的子域名不是合法设置:

  1. Access-Control-Allow-Origin: <origin> | *

也就是要么是指定域名<origin>,要么是简单通配符(*)。就没有第三种了?是的,没有第三种。但我们可以自己动手,通过对配置文件做些修改,用非正常方式达到我们想要的扩展形式,这种扩展形式不仅仅是像“*.yourdomain.com”这样含有通配符的子域名,还可以有更多,完全自己做主,如果自己会写规则的话。

如何设置带通配符子域名的Access-Control-Allow-Origin

上面说到了,规则可以自己做主,但为了简单,也为了满足绝大多数的需求,就以在NGINX下设置成像“*.yourdomain.com”这样含有通配符的子域名作为典型例子。首先找到NGINX服务器的配置文件,通常对站点配置,我们需要修改/etc/nginx/site-enable/your-site-config-file。打开文件后,像下面这样加入一个前置检查,如果匹配的话才动态增加跨域设置。

  1. server {
  2.     root /path/to/your/stuff;
  3.     index index.html index.htm;
  4.     set $match “”;   
  5.   
  6.     if ($http_origin ~* (.*\.yourdomain.com)) {   
  7.         set $match “true”;   
  8.     }   
  9.     server_name yoursweetdomain.com;
  10.     location / {
  11.         if ($match = “true”) {   
  12.             add_header ‘Access-Control-Allow-Origin’ “$http_origin”;   
  13.             add_header ‘Access-Control-Allow-Methods’ ‘GET, POST, OPTIONS, DELETE, PUT’;   
  14.             add_header ‘Access-Control-Allow-Credentials’ ‘true’;   
  15.             add_header ‘Access-Control-Allow-Headers’ ‘User-Agent,Keep-Alive,Content-Type’;   
  16.         }  
  17.         if ($request_method = OPTIONS) {
  18.             return 204;
  19.         }
  20.     }
  21. }

OK,这样就能实现带通配符子域名的安全跨域资源共享了,如果你还需要更复杂的规则,那么就制定你的规则,让你的服务器在跨域资源共享上既有便利性又能兼顾安全性。

>>原创文章,欢迎转载。转载请注明:转载自惠州市卓优互联科技有限公司,谢谢!
>>原文链接地址:设置带通配符子域名的Access-Control-Allow-Origin实现安全跨域资源共享


关于作者

留下您的回复