什么是跨域访问的好解决方案?

时间:2016-06-09 22:54:57

标签: cross-domain

提供跨域访问的最安全方式是什么?  有什么权衡取舍?

我知道我们可以设置跨源访问头,但这需要我的服务器事先知道服务器列表。

1 个答案:

答案 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预检来控制原点,它只是完全避免它们。

https://github.com/jpillora/xdomain