From 80bc66f856092ca81ef9fa945c3c5f16bc1b1bac Mon Sep 17 00:00:00 2001 From: psh686868 Date: Fri, 2 Nov 2018 14:57:07 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=99update:=20Cors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/blade/Blade.java | 14 +++- .../blade/security/web/cors/CorsConfiger.java | 39 ++++++++++ .../security/web/cors/CorsMiddleware.java | 76 ++++++++++++++++++- 3 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/blade/security/web/cors/CorsConfiger.java diff --git a/src/main/java/com/blade/Blade.java b/src/main/java/com/blade/Blade.java index ed9f1a229..5fd08add6 100644 --- a/src/main/java/com/blade/Blade.java +++ b/src/main/java/com/blade/Blade.java @@ -35,6 +35,7 @@ import com.blade.mvc.route.RouteMatcher; import com.blade.mvc.ui.template.DefaultEngine; import com.blade.mvc.ui.template.TemplateEngine; +import com.blade.security.web.cors.CorsConfiger; import com.blade.security.web.cors.CorsMiddleware; import com.blade.server.Server; import com.blade.server.netty.NettyServer; @@ -534,9 +535,20 @@ public Class bootClass() { * @return blade */ public Blade enableCors(boolean enableCors) { + this.enableCors(new CorsConfiger(), enableCors); + return this; + } + + /** + * Set whether to config cors + * @param corsConfig config cors + * @param enableCors enable cors + * @return blade + */ + public Blade enableCors(CorsConfiger corsConfig, boolean enableCors) { this.environment.set(ENV_KEY_CORS_ENABLE, enableCors); if (enableCors) { - this.use(new CorsMiddleware()); + this.use(new CorsMiddleware(corsConfig)); } return this; } diff --git a/src/main/java/com/blade/security/web/cors/CorsConfiger.java b/src/main/java/com/blade/security/web/cors/CorsConfiger.java new file mode 100644 index 000000000..b7bb3c849 --- /dev/null +++ b/src/main/java/com/blade/security/web/cors/CorsConfiger.java @@ -0,0 +1,39 @@ +package com.blade.security.web.cors; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author PSH + * Date: 2018/10/29 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class CorsConfiger { + + public static final String ALL = "*"; + + public static final String DEFAULT_ALLOWED_HEADERS = "Origin, X-Requested-With, Content-Type," + + " Accept, Connection, User-Agent, Cookie, Cache-Control, token"; + + public static final String DEFAULT_ALLOWED_METHODS = "GET, OPTIONS, HEAD, PUT, POST, DELETE"; + + public static final String DEFAULT_ALLOW_CREDENTIALS = "true"; + + public static final Long DEFAULT_MAX_AGE = 1800L; + + + private List allowedMethods; + + private List allowedHeaders; + + private Long maxAge; + + private Boolean allowCredentials; + +} diff --git a/src/main/java/com/blade/security/web/cors/CorsMiddleware.java b/src/main/java/com/blade/security/web/cors/CorsMiddleware.java index db7ba040a..75cc3a50e 100644 --- a/src/main/java/com/blade/security/web/cors/CorsMiddleware.java +++ b/src/main/java/com/blade/security/web/cors/CorsMiddleware.java @@ -2,6 +2,12 @@ import com.blade.mvc.RouteContext; import com.blade.mvc.hook.WebHook; +import com.blade.mvc.http.Request; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.util.internal.StringUtil; +import java.util.StringJoiner; +import java.util.stream.Collector; +import lombok.extern.slf4j.Slf4j; /** * CorsMiddleware @@ -9,18 +15,80 @@ * @author biezhi * @date 2018/7/11 */ +@Slf4j public class CorsMiddleware implements WebHook { + private CorsConfiger corsConfig; + + public CorsMiddleware() { + } + + public CorsMiddleware(CorsConfiger corsConfiger) { + this.corsConfig = corsConfiger; + } + @Override public boolean before(RouteContext context) { - context.header("Access-Control-Allow-Origin", "*"); - context.header("Access-Control-Allow-Credential", "true"); - context.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie, Cache-Control"); - context.header("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD, PUT, POST, DELETE"); + this.allowCredentials(context) + .allowMethods(context) + .allowOrigin(context) + .setMaxAge(context) + .allowCredentials(context); if ("OPTIONS".equals(context.method())) { context.status(202); } return true; } + private CorsMiddleware allowOrigin(RouteContext context) { + Request request = context.request(); + String originUrl = request.header(HttpHeaderNames.ORIGIN.toString()); + if (StringUtil.isNullOrEmpty(originUrl)) { + originUrl = CorsConfiger.ALL; + } + context.header("Access-Control-Allow-Headers", originUrl); + return this; + } + + private CorsMiddleware allowMethods(RouteContext context) { + if (corsConfig == null || corsConfig.getAllowedMethods() == null + || corsConfig.getAllowedMethods().size() == 0) { + + context.header("Access-Control-Allow-Methods", + CorsConfiger.DEFAULT_ALLOWED_METHODS); + return this; + } + + String methods = corsConfig.getAllowedMethods().stream().collect(Collector.of( + () -> new StringJoiner(", "), + (j, method) -> j.add(method.toUpperCase()), + StringJoiner::merge, + StringJoiner::toString + )); + context.response().header("Access-Control-Allow-Methods", methods); + return this; + } + + private CorsMiddleware allowCredentials(RouteContext context) { + if (corsConfig == null || corsConfig.getAllowCredentials() == null) { + context.header("Access-Control-Allow-Credentials", + CorsConfiger.DEFAULT_ALLOW_CREDENTIALS); + return this; + } + context.response().header("Access-Control-Allow-Credentials", + corsConfig.getAllowCredentials().toString()); + return this; + } + + private CorsMiddleware setMaxAge(RouteContext context) { + + if (corsConfig == null || corsConfig.getMaxAge() == null) { + context.response().header("Access-Control-Max-Age", + CorsConfiger.DEFAULT_MAX_AGE.toString()); + return this; + } + context.header(HttpHeaderNames.ACCESS_CONTROL_MAX_AGE.toString(), corsConfig.getMaxAge().toString()); + return this; + } + }