提供跨域访问的最安全方式是什么? 有什么权衡取舍?
我知道我们可以设置跨源访问头,但这需要我的服务器事先知道服务器列表。
答案 0 :(得分:1)
您无需事先了解服务器列表,因为您可以设置Access-Control-Allow-Origin: *
,但这并不像其他网站可以使用您的服务那样安全。因此,请确保在构建标头时允许来自受限列表的Access-Control-Allow-Origin。我只是使用正则表达式来比较,因为我们允许从多个。当我验证匹配时,我将请求原点返回到标题中。因此,如果我匹配web.*energydomain.com
之类的内容并且原点为webservices.energydomain.com
,那么我会传回Access-Control-Allow-Origin: webservices.energydomain.com
这告诉我从此来源接受的呼叫服务(以及任何正在侦听的人)来源,即使我可以接受来自webstart.energydomain.com。
因此,使用spring我们创建了一个过滤器。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setHeader("Access-Control-Allow-Credentials", "true")
//If this is a pre-flight request, make sure that we are allowing them
if ("OPTIONS" == request.method) {
response.setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS")
response.setHeader("Access-Control-Max-Age", "604800")
response.setHeader("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Origin, Vary, Cookie, Key")
//Check to see that the referrer/origin matches the set of allowed origins in the application configuration
String referrer = request.getHeader("Origin")
if (referrer?.matches(ServerProperties.instance.accessControlAllowOriginRegEx)) {
response.setHeader("Access-Control-Allow-Origin", referrer)
}
} else {
//set other headers here and continue chain (we don't bother continuing chain on preflight)
chain.doFilter(request, response)
}
}
您也可以在htaccess上执行此操作
<FilesMatch "\.(ttf|otf|eot|woff)$">
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(webservices.energydomain.com|webservicesmo.energydomain.com|webservicestest.energydomain.com)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
</IfModule>
</FilesMatch>
我更喜欢尝试减少飞行前的交通噪音并避免一起使用。特别是,我使用xdomain。如果使用angular或jQuery,我的设置非常简单。在您的应用服务器上,按照以下链接中的帮助添加proxy.html。添加一些标签,引用“客户”和中提琴上的js文件,不再需要预先飞行。这包含在iframe中以避免需要进行cors检查。您仍然可以像上面所解释的那样使用CORS预检来控制原点,它只是完全避免它们。