netty系列之:在netty中处理CORS
文章目錄
- 簡介
- 服務端的CORS配置
- CorsConfigBuilder
- CorsHandler
- netty對cors的支持
- 總結
簡介
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。
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/
最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!
總結
以上是生活随笔為你收集整理的netty系列之:在netty中处理CORS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux系列之:告诉他,他根本不懂ki
- 下一篇: netty系列之:使用netty搭建we