网关
网关运行分析报告
网关运行分析报告 - 2025-02-15
网关运行分析报告 - 2025-02-22
网关运行分析报告 - 2025-02-28
1.shenyu网关内外网使用
2.shenyu网关的具体使用
记一次网关线上问题之icsp访问ERP
再次思考多套ak/sk同时访问同一资源路径问题
网关接入说明
网关接入说明补充
网关分配各系统命名
网关BUG及二开
网关管理端访问地址
修改requestBody与responseBody
shenyu工程理解
获取requestBody异步问题
shenyu工程部署
排查sign插件报错500问题
shenyu数据结构设计
shenyu网关请求过程
shenyu自定义插件
记一次网关线上问题----网关无法对外提供服务
网关插件更新报错问题
网关中grayTag的使用
Exceeded limit on max bytes to buffer : 262144
网关中Divide插件中Selector中Handler中配置丢失问题
网关请求下游系统时长记录
通用测试:获取网关的sign值
网关分发主数据设想方案
铁骑主数据分发机制完善
27.GTMS&ITMS与gateway的关系
28.ZPI与gateway的关系
26.网关验签场景
29.PC端空值,服务端正常请求
30.网关requestMaxSize值
31.跨系统跨语言日志链路追踪
32.网关异步分发讨论
33.网关LoggingConsole丢失日志排查
34.网关升级shenyu-admin
35.网关异步分发插件 - 接入文档
本文档使用「觅思文档专业版」发布
-
+
首页
获取requestBody异步问题
对接TMS时候,TMS的验签规则是对requestBody的内容进行加密。 ## 1.现象 实现代码如下 ``` @Override protected Mono<Void> doExecute(ServerWebExchange exchange, ShenyuPluginChain chain, SelectorData selector, RuleData ruleData) { LOGGER.debug(".......... TmsSignaturePlugin start.............."); TmsSignSelectorHandle tmsSignSelectorHandle = TmsSignPluginSelectorDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(selector)); if (Objects.isNull(tmsSignSelectorHandle)) { LOGGER.error("eaalogin handler can not configuration:{}", tmsSignSelectorHandle); return chain.execute(exchange); } String requestUrl = exchange.getRequest().getPath().toString(); String apiCode = requestUrl.substring(requestUrl.lastIndexOf("/")+1); List<HttpMessageReader<?>> MESSAGE_READERS = HandlerStrategies.builder().build().messageReaders(); ServerRequest serverRequest = ServerRequest.create(exchange, MESSAGE_READERS); StringBuilder requestBody =new StringBuilder(); Mono<String> mono = serverRequest.bodyToMono(String.class).switchIfEmpty(Mono.defer(() -> Mono.just(""))).flatMap(originalBody -> { LOGGER.info("get body data success data:{}", originalBody); requestBody.append(originalBody); return Mono.just(originalBody); }); BodyInserter<Mono<String>, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromPublisher(mono, String.class); HttpHeaders headers = new HttpHeaders(); headers.putAll(exchange.getRequest().getHeaders()); headers.remove(HttpHeaders.CONTENT_LENGTH); //tms need header long timestamp = System.currentTimeMillis(); StringBuilder builder = new StringBuilder(); builder.append("apiCode").append(apiCode); builder.append("appKey").append(tmsSignSelectorHandle.getAppKey()); builder.append("clientId").append(tmsSignSelectorHandle.getClientId()); builder.append("version").append(version); builder.append("timestamp").append(timestamp); builder.append("content").append(requestBody); builder.append(tmsSignSelectorHandle.getSecret()); String signTmp = builder.toString(); String sign = Md5Utils.getMd5Code(signTmp); headers.set("sign",sign); headers.set("appKey",tmsSignSelectorHandle.getAppKey()); headers.set("timestamp",String.valueOf(timestamp)); headers.set("version",TmsSignaturePlugin.version); headers.set("clientId",tmsSignSelectorHandle.getClientId()); CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers); return bodyInserter.insert(outputMessage, new BodyInserterContext()) .then(Mono.defer(() -> { ServerHttpRequestDecorator decorator = new ModifyServerHttpRequestDecorator(headers, exchange.getRequest(), outputMessage); return chain.execute(exchange.mutate().request(decorator).build()); })).onErrorResume(error -> { if (error instanceof ResponsiveException) { return WebFluxResultUtils.failedResult((ResponsiveException) error); } return Mono.error(error); }); } ``` 解读如下:  实际运行过程中,发现这段代码是异步的 ``` Mono<String> mono = serverRequest.bodyToMono(String.class).switchIfEmpty(Mono.defer(() -> Mono.just(""))).flatMap(originalBody -> { LOGGER.info("get body data success data:{}", originalBody); requestBody.append(originalBody); return Mono.just(originalBody); }); ``` 即下面的代码 ``` builder.append("content").append(requestBody); ``` 这里用于加密的requestBody是空值。导致TMS验签一直没有通过。 ## 2.解决方案 代码如下 ``` @Override protected Mono<Void> doExecute(ServerWebExchange exchange, ShenyuPluginChain chain, SelectorData selector, RuleData ruleData) { LOGGER.debug(".......... TmsSignaturePlugin start.............."); TmsSignSelectorHandle tmsSignSelectorHandle = TmsSignPluginSelectorDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(selector)); if (Objects.isNull(tmsSignSelectorHandle)) { LOGGER.error("eaalogin handler can not configuration:{}", tmsSignSelectorHandle); return chain.execute(exchange); } String requestUrl = exchange.getRequest().getPath().toString(); String apiCode = requestUrl.substring(requestUrl.lastIndexOf("/")+1); List<HttpMessageReader<?>> MESSAGE_READERS = HandlerStrategies.builder().build().messageReaders(); ServerRequest serverRequest = ServerRequest.create(exchange, MESSAGE_READERS); StringBuilder requestBody =new StringBuilder(); Mono<String> mono = serverRequest.bodyToMono(String.class).switchIfEmpty(Mono.defer(() -> Mono.just(""))).flatMap(originalBody -> { LOGGER.info("get body data success data:{}", originalBody); requestBody.append(originalBody); return Mono.just(originalBody); }); BodyInserter<Mono<String>, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromPublisher(mono, String.class); HttpHeaders headers = new HttpHeaders(); headers.putAll(exchange.getRequest().getHeaders()); headers.remove(HttpHeaders.CONTENT_LENGTH); CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers); return bodyInserter.insert(outputMessage, new BodyInserterContext()) .then(Mono.defer(() -> { //tms need header long timestamp = System.currentTimeMillis(); StringBuilder builder = new StringBuilder(); builder.append("apiCode").append(apiCode); builder.append("appKey").append(tmsSignSelectorHandle.getAppKey()); builder.append("clientId").append(tmsSignSelectorHandle.getClientId()); builder.append("version").append(version); builder.append("timestamp").append(timestamp); builder.append("content").append(requestBody); builder.append(tmsSignSelectorHandle.getSecret()); String signTmp = builder.toString(); String sign = Md5Utils.getMd5Code(signTmp); headers.set("sign",sign); headers.set("appKey",tmsSignSelectorHandle.getAppKey()); headers.set("timestamp",String.valueOf(timestamp)); headers.set("version",TmsSignaturePlugin.version); headers.set("clientId",tmsSignSelectorHandle.getClientId()); ServerHttpRequestDecorator decorator = new ModifyServerHttpRequestDecorator(headers, exchange.getRequest(), outputMessage); return chain.execute(exchange.mutate().request(decorator).build()); })).onErrorResume(error -> { if (error instanceof ResponsiveException) { return WebFluxResultUtils.failedResult((ResponsiveException) error); } return Mono.error(error); }); } ``` 解读如下: 
李贤利
2023年8月1日 16:36
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文件
PDF文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
有效期