写点什么

netty 系列之: 在 netty 中处理 CORS

发布于: 2 小时前

简介 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: trueallowedRequestMethods 表示访问资源允许的方法,主要用在 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。


CorsConfigBuilderCorsConfig 使用来表示 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/


最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!


欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 2 小时前阅读数: 11
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
netty系列之:在netty中处理CORS