共计 3552 个字符,预计需要花费 9 分钟才能阅读完成。
简介
CORS 的全称是跨域资源共享,他是一个基于 HTTP-header 检测的机制,通过对 HTTP-header 进行管制,能够实现对跨域资源的权限治理性能。在之前的 CORS 详解文章中,咱们曾经对 CORS 有了根本的解释。
本文将会从 netty 的实现角度,解说如何在 netty 中实现 CORS。
服务端的 CORS 配置
相熟 CORS 的敌人应该晓得,CORS 所有的操作都是在 HTTP 协定之上通过管制 HTTP 头来实现的。所以说如果要在服务器端实现 CORS 的反对,事实上也是对 HTTP 协定的头进行各种设置实现的。
为了不便大家的应用,netty 提供了一个 CorsConfig 类,来对立 CORS 的头设置。
先看下 CorsConfig 类中定义的属性:
private final Set<String> origins;
private final boolean anyOrigin;
private final boolean enabled;
private final Set<String> exposeHeaders;
private final boolean allowCredentials;
private final long maxAge;
private final Set<HttpMethod> allowedRequestMethods;
private final Set<String> allowedRequestHeaders;
private final boolean allowNullOrigin;
private final Map<CharSequence, Callable<?>> preflightHeaders;
private final boolean shortCircuit;
这些属性和 CORS 的 HTTP 头设置是一一对应的。比如说 origins 示意的是容许的源,anyOrigin 示意容许所有的源。
是和上面的设置对应的:
Origin: <origin>
exposeHeaders 是和 Access-Control-Expose-Headers 一一对应的,示意服务器端容许客户端获取 CORS 资源的同时可能拜访到的 header 信息。其格局如下:
Access-Control-Expose-Headers: <header-name>[, <header-name>]*
allowCredentials 示意是否开启 CORS 的权限认证。示意服务器端是否承受客户端带有 credentials 字段的申请。如果用在 preflight 申请中,则示意后续的实在申请是否反对 credentials,其格局如下:
Access-Control-Allow-Credentials: true
allowedRequestMethods 示意拜访资源容许的办法,次要用在 preflight request 中。其格局如下:
Access-Control-Allow-Methods: <method>[, <method>]*
allowedRequestHeaders 用在 preflight request 中,示意真正可能被用来做申请的 header 字段,其格局如下:
Access-Control-Allow-Headers: <header-name>[, <header-name>]*
当客户端发送 OPTIONS 办法给服务器的时候,为了平安起见,因为服务器并不一定可能承受这些 OPTIONS 的办法,所以客户端须要首先发送一个
preflighted requests,期待服务器响应,等服务器确认之后,再发送实在的申请。咱们举一个例子。preflightHeaders 示意的就是服务器容许额 preflight 的申请头。
shortCircuit 示意申请是否是一个无效的 CORS 申请,如果申请被回绝之后,就会返回一个 true。
CorsConfigBuilder
CorsConfig 应用来示意 Cors 的配置类,那么怎么去结构这个配置类呢?咱们看下 CorsConfig 的构造函数:
CorsConfig(final CorsConfigBuilder builder) {origins = new LinkedHashSet<String>(builder.origins);
anyOrigin = builder.anyOrigin;
enabled = builder.enabled;
exposeHeaders = builder.exposeHeaders;
allowCredentials = builder.allowCredentials;
maxAge = builder.maxAge;
allowedRequestMethods = builder.requestMethods;
allowedRequestHeaders = builder.requestHeaders;
allowNullOrigin = builder.allowNullOrigin;
preflightHeaders = builder.preflightHeaders;
shortCircuit = builder.shortCircuit;
}
能够看到 CorsConfig 是通过 CorsConfigBuilder 来结构的。通过设置 CorsConfigBuilder 中的各种属性即可。CorsConfigBuilder 中提供了多种设置属性的办法。
能够应用这样的办法来结构 CorsConfig 如下:
CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();
CorsHandler
有了 corsConfig,咱们还须要将这个 config 配置在 netty 的 handler 中,netty 提供了一个 CorsHandler 类来专门解决 corsConfig, 这个类就叫 CorsHandler。
首先看下 CorsHandler 的构造函数:
public CorsHandler(final CorsConfig config) {this(Collections.singletonList(checkNotNull(config, "config")), config.isShortCircuit());
}
public CorsHandler(final List<CorsConfig> configList, boolean isShortCircuit) {checkNonEmpty(configList, "configList");
this.configList = configList;
this.isShortCircuit = isShortCircuit;
}
CorsHandler 有两个构造函数,一个是传入 CorsConfig,一个是传入一个 CorsConfig 的列表。
CorsHandler 的次要工作原理就是在 channelRead 的时候,对 responseHeader 进行解决,设置 CORS 头。
netty 对 cors 的反对
下面咱们曾经讲过了 netty 中 cors 的外围类和办法,最初一步就是把 cors 的反对类退出到 netty 的 pipeline 中,其外围代码如下:
public void initChannel(SocketChannel ch) {ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpResponseEncoder());
pipeline.addLast(new HttpRequestDecoder());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new ChunkedWriteHandler());
CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();
pipeline.addLast(new CorsHandler(corsConfig));
pipeline.addLast(new CustResponseHandler());
}
总结
cors 比较简单,netty 也为其提供了住够的办法反对。大家能够间接应用。
本文的例子能够参考:learn-netty4
本文已收录于 http://www.flydean.com/22-netty-cors/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!