From a08313ea817f1de8a79e64fff33ce89c591b8a90 Mon Sep 17 00:00:00 2001 From: tanghc Date: Sat, 26 Oct 2019 15:54:48 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BD=91=E5=85=B3=E5=8F=AF=E6=A0=A1=E9=AA=8Cto?= =?UTF-8?q?ken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 4 ++ doc/docs/_sidebar.md | 65 ++++++++++--------- doc/docs/files/10089_自定义校验token.md | 54 +++++++++++++++ sop-2.5.0.sql | 1 + .../api/service/param/RouteSearchParam.java | 4 ++ .../api/service/result/RouteVO.java | 3 + .../entity/ConfigServiceRoute.java | 3 + .../src/main/resources/public/index.html | 2 +- .../static/js/chunk-9b31c83a.52bc6b2c.js | 1 + .../static/js/chunk-9b31c83a.e60adb43.js | 1 - .../sop-admin-vue/src/views/service/route.vue | 17 +++++ .../sop/gatewaycommon/bean/ApiConfig.java | 7 ++ .../bean/BaseRouteDefinition.java | 46 ------------- .../bean/BaseServiceRouteInfo.java | 19 ------ .../gatewaycommon/bean/RouteDefinition.java | 5 ++ .../BaseGatewayConfiguration.java | 27 ++++++-- .../manager/EnvironmentKeys.java | 7 +- .../gatewaycommon/validate/ApiValidator.java | 22 ++++++- .../validate/TokenValidator.java | 11 ++++ .../servercommon/annotation/ApiAbility.java | 5 ++ .../servercommon/annotation/ApiMapping.java | 7 +- .../sop/servercommon/bean/OpenContext.java | 13 +++- .../sop/servercommon/bean/ServiceApiInfo.java | 2 + .../servercommon/manager/ApiMetaBuilder.java | 1 + .../manager/ServiceRouteInfoBuilder.java | 4 +- .../mapping/ApiMappingHandlerMapping.java | 10 ++- .../servercommon/mapping/ApiMappingInfo.java | 1 + .../servercommon/route/RouteDefinition.java | 5 ++ .../storyweb/controller/TokenController.java | 28 ++++++++ .../gateway/entity/ConfigServiceRoute.java | 7 +- .../gateway/manager/DbRoutesProcessor.java | 1 + .../main/java/com/gitee/sop/test/Client.java | 15 +++++ .../java/com/gitee/sop/test/AllInOneTest.java | 11 ++++ 33 files changed, 293 insertions(+), 116 deletions(-) create mode 100644 doc/docs/files/10089_自定义校验token.md create mode 100644 sop-2.5.0.sql create mode 100644 sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.52bc6b2c.js delete mode 100644 sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.e60adb43.js delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java delete mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/TokenValidator.java create mode 100644 sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/TokenController.java diff --git a/changelog.md b/changelog.md index 6249dd9a..dd4d0905 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # changelog +## 2.5.0 + +- 网关可校验token,见`com.gitee.sop.storyweb.controller.TokenController`(需要执行`sop-2.5.0.sql`升级文件) + ## 2.4.1 - 优化restful接口调用(如果正在使用此功能,必看 [doc](https://durcframework.gitee.io/sop/#/files/10100_%E6%8F%90%E4%BE%9Brestful%E6%8E%A5%E5%8F%A3?t=1571107529449)) diff --git a/doc/docs/_sidebar.md b/doc/docs/_sidebar.md index 38a92c3e..6270b7b6 100644 --- a/doc/docs/_sidebar.md +++ b/doc/docs/_sidebar.md @@ -1,34 +1,35 @@ -* [首页](/?t=1571107529420) +* [首页](/?t=1572076365237) * 开发文档 - * [快速体验](files/10010_快速体验.md?t=1571107529423) - * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1571107529447) - * [新增接口](files/10020_新增接口.md?t=1571107529447) - * [开发流程](files/10021_开发流程.md?t=1571107529447) - * [业务参数校验](files/10030_业务参数校验.md?t=1571107529447) - * [错误处理](files/10040_错误处理.md?t=1571107529447) - * [编写文档](files/10041_编写文档.md?t=1571107529447) - * [接口交互详解](files/10050_接口交互详解.md?t=1571107529448) - * [easyopen支持](files/10070_easyopen支持.md?t=1571107529448) - * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1571107529448) - * [ISV管理](files/10085_ISV管理.md?t=1571107529448) - * [自定义返回结果](files/10087_自定义返回结果.md?t=1571107529448) - * [自定义过滤器](files/10088_自定义过滤器.md?t=1571107529448) - * [路由授权](files/10090_路由授权.md?t=1571107529448) - * [接口限流](files/10092_接口限流.md?t=1571107529448) - * [监控日志](files/10093_监控日志.md?t=1571107529448) - * [SDK开发](files/10095_SDK开发.md?t=1571107529449) - * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1571107529449) - * [应用授权](files/10097_应用授权.md?t=1571107529449) - * [提供restful接口](files/10100_提供restful接口.md?t=1571107529449) - * [文件上传](files/10104_文件上传.md?t=1571107529449) - * [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1571107529449) - * [预发布灰度发布](files/10110_预发布灰度发布.md?t=1571107529449) - * [动态修改请求参数](files/10111_动态修改请求参数.md?t=1571107529450) - * [使用eureka](files/10112_使用eureka.md?t=1571107529450) - * [扩展其它注册中心](files/10113_扩展其它注册中心.md?t=1571107529450) + * [快速体验](files/10010_快速体验.md?t=1572076365239) + * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1572076365257) + * [新增接口](files/10020_新增接口.md?t=1572076365257) + * [开发流程](files/10021_开发流程.md?t=1572076365257) + * [业务参数校验](files/10030_业务参数校验.md?t=1572076365258) + * [错误处理](files/10040_错误处理.md?t=1572076365258) + * [编写文档](files/10041_编写文档.md?t=1572076365258) + * [接口交互详解](files/10050_接口交互详解.md?t=1572076365258) + * [easyopen支持](files/10070_easyopen支持.md?t=1572076365258) + * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1572076365258) + * [ISV管理](files/10085_ISV管理.md?t=1572076365258) + * [自定义返回结果](files/10087_自定义返回结果.md?t=1572076365259) + * [自定义过滤器](files/10088_自定义过滤器.md?t=1572076365259) + * [自定义校验token](files/10089_自定义校验token.md?t=1572076365259) + * [路由授权](files/10090_路由授权.md?t=1572076365259) + * [接口限流](files/10092_接口限流.md?t=1572076365259) + * [监控日志](files/10093_监控日志.md?t=1572076365259) + * [SDK开发](files/10095_SDK开发.md?t=1572076365259) + * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1572076365260) + * [应用授权](files/10097_应用授权.md?t=1572076365260) + * [提供restful接口](files/10100_提供restful接口.md?t=1572076365260) + * [文件上传](files/10104_文件上传.md?t=1572076365260) + * [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1572076365260) + * [预发布灰度发布](files/10110_预发布灰度发布.md?t=1572076365261) + * [动态修改请求参数](files/10111_动态修改请求参数.md?t=1572076365261) + * [使用eureka](files/10112_使用eureka.md?t=1572076365261) + * [扩展其它注册中心](files/10113_扩展其它注册中心.md?t=1572076365261) * 原理分析 - * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1571107529450) - * [原理分析之如何存储路由](files/90011_原理分析之如何存储路由.md?t=1571107529450) - * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1571107529450) - * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1571107529450) - * [常见问题](files/90100_常见问题.md?t=1571107529450) + * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1572076365261) + * [原理分析之如何存储路由](files/90011_原理分析之如何存储路由.md?t=1572076365261) + * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1572076365261) + * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1572076365262) + * [常见问题](files/90100_常见问题.md?t=1572076365262) diff --git a/doc/docs/files/10089_自定义校验token.md b/doc/docs/files/10089_自定义校验token.md new file mode 100644 index 00000000..365e77c2 --- /dev/null +++ b/doc/docs/files/10089_自定义校验token.md @@ -0,0 +1,54 @@ +# 自定义校验token(2.5.0) + +从2.5.0开始在`@ApiMapping`注解中新增了一个属性`needToken`,用来告诉网关是否校验token + +```java +/** +* 是否需要appAuthToken,设置为true,网关端会校验token是否存在 +*/ +boolean needToken() default false; +``` + +使用方式: + +```java +@ApiMapping(value = "story.token.get", needToken = true/* 设置true,网关会校验token是否存在 */) +public StoryResult token(StoryParam story) { + OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext(); + String appAuthToken = openContext.getAppAuthToken(); + StoryResult result = new StoryResult(); + result.setName("appAuthToken:" + appAuthToken); + return result; +} +``` + +指定了needToken=true后,网关会判断客户端是否传了`app_auth_token`参数,没有传则返回错误信息。 + +网关默认简单校验参数值是否存在,如果要校验有效性,需要自己实现。 + +自己实现步骤: + +- 在ZuulConfig类中重写`doAfter`方法 +- 设置`ApiConfig中的tokenValidator属性` + +`TokenValidator`是一个函数式接口,可以直接使用Lambda表达式,示例代码如下: + +```java +public class ZuulConfig extends AlipayZuulConfiguration { + + @Override + protected void doAfter() { + ApiConfig.getInstance().setTokenValidator(apiParam -> { + // 获取客户端传递过来的token + String token = apiParam.fetchAccessToken(); + if (StringUtils.isBlank(token)) { + return false; + } + // TODO: 校验token有效性,可以从redis中读取 + + // 返回true表示这个token真实、有效 + return true; + }); + } +} +``` diff --git a/sop-2.5.0.sql b/sop-2.5.0.sql new file mode 100644 index 00000000..5743cdad --- /dev/null +++ b/sop-2.5.0.sql @@ -0,0 +1 @@ +ALTER TABLE `sop`.`config_service_route` ADD COLUMN `need_token` TINYINT NOT NULL DEFAULT 0 COMMENT '是否需要token' AFTER `permission`; diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/RouteSearchParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/RouteSearchParam.java index 46205320..9a1819e5 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/RouteSearchParam.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/RouteSearchParam.java @@ -26,4 +26,8 @@ public class RouteSearchParam extends PageParam { @ApiDocField(description = "是否授权接口,1:是") @Condition(ignoreValue = "0") private Integer permission; + + @ApiDocField(description = "是否需要token接口,1:是") + @Condition(ignoreValue = "0") + private Integer needToken; } diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/RouteVO.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/RouteVO.java index c189ab70..9c548c9a 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/RouteVO.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/RouteVO.java @@ -49,6 +49,9 @@ public class RouteVO { /** 是否合并结果, 数据库字段:merge_result */ private Byte mergeResult; + /** 是否需要token, 数据库字段:need_token */ + private Byte needToken; + /** 是否需要授权才能访问, 数据库字段:permission */ private Byte permission; diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigServiceRoute.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigServiceRoute.java index 369b2e42..0234fb21 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigServiceRoute.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigServiceRoute.java @@ -61,6 +61,9 @@ public class ConfigServiceRoute { /** 是否需要授权才能访问, 数据库字段:permission */ private Byte permission; + /** 是否需要token, 数据库字段:need_token */ + private Byte needToken; + /** 数据库字段:gmt_create */ private Date gmtCreate; diff --git a/sop-admin/sop-admin-server/src/main/resources/public/index.html b/sop-admin/sop-admin-server/src/main/resources/public/index.html index ff0b6f35..359b4615 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/index.html +++ b/sop-admin/sop-admin-server/src/main/resources/public/index.html @@ -1 +1 @@ -SOP Admin
\ No newline at end of file +SOP Admin
\ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.52bc6b2c.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.52bc6b2c.js new file mode 100644 index 00000000..7b966db8 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.52bc6b2c.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-9b31c83a"],{"048e":function(e,t,o){},"0ce7":function(e,t,o){"use strict";var i=o("048e"),a=o.n(i);a.a},"5f67":function(e,t,o){"use strict";o.r(t);var i=function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("div",{staticClass:"app-container"},[o("el-container",[o("el-aside",{staticStyle:{"min-height":"300px",width:"250px"}},[o("el-button",{staticStyle:{display:"none"},attrs:{type:"primary",plain:"",size:"mini",icon:"el-icon-plus"},on:{click:function(t){return t.stopPropagation(),e.addService(t)}}},[e._v("\n 新建服务\n ")]),e._v(" "),o("el-input",{staticStyle:{"margin-bottom":"10px","margin-top":"10px"},attrs:{"prefix-icon":"el-icon-search",placeholder:"搜索服务...",size:"mini",clearable:""},model:{value:e.filterText,callback:function(t){e.filterText=t},expression:"filterText"}}),e._v(" "),o("el-tree",{ref:"serviceTree",staticClass:"filter-tree",attrs:{data:e.treeData,props:e.defaultProps,"filter-node-method":e.filterNode,"highlight-current":!0,"expand-on-click-node":!1,"empty-text":"无数据","node-key":"serviceId","default-expand-all":""},on:{"node-click":e.onNodeClick},scopedSlots:e._u([{key:"default",fn:function(t){t.node;var i=t.data;return o("span",{staticClass:"custom-tree-node"},[o("div",[o("el-tooltip",{directives:[{name:"show",rawName:"v-show",value:i.custom,expression:"data.custom"}],staticClass:"item",attrs:{content:"自定义服务",effect:"light",placement:"left"}},[o("i",{staticClass:"el-icon-warning-outline"})]),e._v(" "),i.label.length0?t.join(", "):'未授权'},onRouteDialogSave:function(){var e=this;this.$refs.routeDialogFormRef.validate(function(t){if(t){var o=e.routeDialogFormData.id?"route.update":"route.add";e.routeDialogFormData.serviceId=e.serviceId,e.post(o,e.routeDialogFormData,function(){this.routeDialogVisible=!1,this.loadTable()})}})},onAuthDialogSave:function(){this.post("route.role.update",this.authDialogFormData,function(){this.authDialogVisible=!1,this.loadTable()})},addService:function(){this.addServiceDialogVisible=!0},closeAddServiceDlg:function(){this.$refs.addServiceForm.resetFields()},onAddService:function(){var e=this;this.$refs.addServiceForm.validate(function(t){t&&e.post("service.custom.add",e.addServiceForm,function(e){this.addServiceDialogVisible=!1,this.tip("添加成功"),this.loadTree()})})},onDelService:function(e){var t=e.serviceId;this.confirm("确认要删除服务"+t+"吗,【对应的路由配置会一起删除】",function(e){var o={serviceId:t};this.post("service.custom.del",o,function(){e(),this.tip("删除成功"),this.loadTree()})})},onSizeChange:function(e){this.searchFormData.pageSize=e,this.loadTable()},onPageIndexChange:function(e){this.searchFormData.pageIndex=e,this.loadTable()}}},l=r,s=(o("0ce7"),o("2877")),n=Object(s["a"])(l,i,a,!1,null,null,null);t["default"]=n.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.e60adb43.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.e60adb43.js deleted file mode 100644 index 4831025f..00000000 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9b31c83a.e60adb43.js +++ /dev/null @@ -1 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-9b31c83a"],{"048e":function(e,t,i){},"0ce7":function(e,t,i){"use strict";var o=i("048e"),a=i.n(o);a.a},"5f67":function(e,t,i){"use strict";i.r(t);var o=function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",{staticClass:"app-container"},[i("el-container",[i("el-aside",{staticStyle:{"min-height":"300px",width:"250px"}},[i("el-button",{staticStyle:{display:"none"},attrs:{type:"primary",plain:"",size:"mini",icon:"el-icon-plus"},on:{click:function(t){return t.stopPropagation(),e.addService(t)}}},[e._v("\n 新建服务\n ")]),e._v(" "),i("el-input",{staticStyle:{"margin-bottom":"10px","margin-top":"10px"},attrs:{"prefix-icon":"el-icon-search",placeholder:"搜索服务...",size:"mini",clearable:""},model:{value:e.filterText,callback:function(t){e.filterText=t},expression:"filterText"}}),e._v(" "),i("el-tree",{ref:"serviceTree",staticClass:"filter-tree",attrs:{data:e.treeData,props:e.defaultProps,"filter-node-method":e.filterNode,"highlight-current":!0,"expand-on-click-node":!1,"empty-text":"无数据","node-key":"serviceId","default-expand-all":""},on:{"node-click":e.onNodeClick},scopedSlots:e._u([{key:"default",fn:function(t){t.node;var o=t.data;return i("span",{staticClass:"custom-tree-node"},[i("div",[i("el-tooltip",{directives:[{name:"show",rawName:"v-show",value:o.custom,expression:"data.custom"}],staticClass:"item",attrs:{content:"自定义服务",effect:"light",placement:"left"}},[i("i",{staticClass:"el-icon-warning-outline"})]),e._v(" "),o.label.length0?t.join(", "):'未授权'},onRouteDialogSave:function(){var e=this;this.$refs.routeDialogFormRef.validate(function(t){if(t){var i=e.routeDialogFormData.id?"route.update":"route.add";e.routeDialogFormData.serviceId=e.serviceId,e.post(i,e.routeDialogFormData,function(){this.routeDialogVisible=!1,this.loadTable()})}})},onAuthDialogSave:function(){this.post("route.role.update",this.authDialogFormData,function(){this.authDialogVisible=!1,this.loadTable()})},addService:function(){this.addServiceDialogVisible=!0},closeAddServiceDlg:function(){this.$refs.addServiceForm.resetFields()},onAddService:function(){var e=this;this.$refs.addServiceForm.validate(function(t){t&&e.post("service.custom.add",e.addServiceForm,function(e){this.addServiceDialogVisible=!1,this.tip("添加成功"),this.loadTree()})})},onDelService:function(e){var t=e.serviceId;this.confirm("确认要删除服务"+t+"吗,【对应的路由配置会一起删除】",function(e){var i={serviceId:t};this.post("service.custom.del",i,function(){e(),this.tip("删除成功"),this.loadTree()})})},onSizeChange:function(e){this.searchFormData.pageSize=e,this.loadTable()},onPageIndexChange:function(e){this.searchFormData.pageIndex=e,this.loadTable()}}},l=r,s=(i("0ce7"),i("2877")),n=Object(s["a"])(l,o,a,!1,null,null,null);t["default"]=n.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-vue/src/views/service/route.vue b/sop-admin/sop-admin-vue/src/views/service/route.vue index 5686365e..32d99639 100644 --- a/sop-admin/sop-admin-vue/src/views/service/route.vue +++ b/sop-admin/sop-admin-vue/src/views/service/route.vue @@ -66,6 +66,9 @@ 授权接口 + + 需要token + 查询 @@ -123,6 +126,16 @@ + + + {{ routeDialogFormData.mergeResult === 1 ? '是' : '否' }} + + {{ routeDialogFormData.needToken === 1 ? '是' : '否' }} + 启用 @@ -269,6 +285,7 @@ export default { id: '', serviceId: '', permission: 0, + needToken: 0, pageIndex: 1, pageSize: 10 }, diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java index a61e9f6a..34ee0bb1 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java @@ -32,12 +32,14 @@ import com.gitee.sop.gatewaycommon.validate.ApiSigner; import com.gitee.sop.gatewaycommon.validate.ApiValidator; import com.gitee.sop.gatewaycommon.validate.Encrypter; import com.gitee.sop.gatewaycommon.validate.Signer; +import com.gitee.sop.gatewaycommon.validate.TokenValidator; import com.gitee.sop.gatewaycommon.validate.Validator; import com.gitee.sop.gatewaycommon.zuul.configuration.ZuulErrorController; import com.gitee.sop.gatewaycommon.zuul.param.ZuulParamBuilder; import com.gitee.sop.gatewaycommon.zuul.result.ZuulResultExecutor; import com.netflix.zuul.context.RequestContext; import lombok.Data; +import org.apache.commons.lang3.StringUtils; import org.springframework.web.server.ServerWebExchange; import java.util.ArrayList; @@ -152,6 +154,11 @@ public class ApiConfig { private ParameterFormatter parameterFormatter; + /** + * 校验token + */ + private TokenValidator tokenValidator = apiParam -> apiParam != null && StringUtils.isNotBlank(apiParam.fetchAccessToken()); + // -------- fields --------- /** diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java deleted file mode 100644 index e46e6671..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.gitee.sop.gatewaycommon.bean; - -import lombok.Getter; -import lombok.Setter; - -/** - * @author tanghc - */ -@Getter -@Setter -public class BaseRouteDefinition { - - /** - * 路由的Id - */ - private String id; - /** - * 路由规则转发的目标uri - */ - private String uri; - - /** - * uri后面跟的path - */ - private String path; - - /** - * 路由执行的顺序 - */ - private int order = 0; - - /** - * 是否忽略验证,业务参数验证除外 - */ - private int ignoreValidate; - - /** - * 是否合并结果 - */ - private int mergeResult; - - /** - * 接口是否需要授权才能访问 - */ - private int permission; -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java deleted file mode 100644 index a66d0f17..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseServiceRouteInfo.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.gitee.sop.gatewaycommon.bean; - -import lombok.Data; - -import java.util.Collections; -import java.util.List; - -/** - * @author tanghc - */ -@Data -public class BaseServiceRouteInfo { - private String serviceId; - private List routeDefinitionList = Collections.emptyList(); - - public String fetchServiceIdLowerCase() { - return this.serviceId.toLowerCase(); - } -} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/RouteDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/RouteDefinition.java index 8cfd257d..eb6fba9f 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/RouteDefinition.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/RouteDefinition.java @@ -70,4 +70,9 @@ public class RouteDefinition { * 是否需要授权才能访问 */ private int permission; + + /** + * 是否需要token + */ + private int needToken; } \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java index 1b92d609..7df72e6f 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java @@ -16,6 +16,8 @@ import com.gitee.sop.gatewaycommon.manager.AbstractConfiguration; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; import com.gitee.sop.gatewaycommon.param.ParamBuilder; import com.gitee.sop.gatewaycommon.param.ParamNames; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -25,13 +27,19 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.util.MultiValueMap; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.RequestPredicate; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; import java.net.URI; import java.util.Collections; @@ -41,6 +49,7 @@ import java.util.List; /** * @author tanghc */ +@Slf4j public class BaseGatewayConfiguration extends AbstractConfiguration { public BaseGatewayConfiguration() { @@ -152,12 +161,20 @@ public class BaseGatewayConfiguration extends AbstractConfiguration { @Bean @ConditionalOnProperty(value = "sop.restful.enable", havingValue = "true") RouterFunction routerFunction() { - return RouterFunctions.route(RequestPredicates.GET(restPath + "/**"), (serverRequest) -> { - String url = serverRequest.path(); - int index = url.indexOf(restPath); + RequestPredicate requestPredicate = RequestPredicates.all() + .and(RequestPredicates.path(restPath + "/**")); + return RouterFunctions.route(requestPredicate, (serverRequest) -> { + String path = serverRequest.path(); + int index = path.indexOf(restPath); // 取/rest的后面部分 - String path = url.substring(index + restPath.length()); - String query = ParamNames.API_NAME + "=" + path + "&" + ParamNames.VERSION_NAME + "="; + String servletPath = path.substring(index + restPath.length()); + String query = serverRequest.uri().getQuery(); + String appendQuery = ParamNames.API_NAME + "=" + servletPath + "&" + ParamNames.VERSION_NAME + "="; + if (StringUtils.isBlank(query)) { + query = appendQuery; + } else { + query += '&' + appendQuery; + } return ServerResponse .temporaryRedirect(URI.create("/?" + query)) .build(); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvironmentKeys.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvironmentKeys.java index 5ff62d11..3590c040 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvironmentKeys.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvironmentKeys.java @@ -21,7 +21,12 @@ public enum EnvironmentKeys { /** * sop.restful.enable=true,开启传统web开发模式 */ - SOP_RESTFUL_ENABLE("sop.restful.enable"); + SOP_RESTFUL_ENABLE("sop.restful.enable"), + + /** + * sop.restful.path=/xx ,指定请求前缀,默认/rest + */ + SOP_RESTFUL_PATH("sop.restful.path", "/rest"); private String key; private String defaultValue; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java index 7d4abb2b..8bdf8f24 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java @@ -83,6 +83,7 @@ public class ApiValidator implements Validator { checkFormat(param); checkUploadFile(param); checkPermission(param); + checkToken(param); } /** @@ -238,7 +239,7 @@ public class ApiValidator implements Validator { /** * 校验访问权限 * - * @param apiParam + * @param apiParam 参数 */ protected void checkPermission(ApiParam apiParam) { String routeId = apiParam.fetchNameVersion(); @@ -254,4 +255,23 @@ public class ApiValidator implements Validator { } } + /** + * 校验token + * + * @param apiParam 参数 + */ + protected void checkToken(ApiParam apiParam) { + String routeId = apiParam.fetchNameVersion(); + TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId); + RouteDefinition routeDefinition = targetRoute.getRouteDefinition(); + boolean needToken = BooleanUtils.toBoolean(routeDefinition.getNeedToken()); + if (needToken) { + TokenValidator tokenValidator = ApiConfig.getInstance().getTokenValidator(); + boolean rightToken = tokenValidator.validateToken(apiParam); + if (!rightToken) { + throw ErrorEnum.AOP_INVALID_APP_AUTH_TOKEN.getErrorMeta().getException(); + } + } + } + } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/TokenValidator.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/TokenValidator.java new file mode 100644 index 00000000..42959fbf --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/TokenValidator.java @@ -0,0 +1,11 @@ +package com.gitee.sop.gatewaycommon.validate; + +import com.gitee.sop.gatewaycommon.param.ApiParam; + +/** + * @author tanghc + */ +@FunctionalInterface +public interface TokenValidator { + boolean validateToken(ApiParam apiParam); +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java index 44dbf4d0..9283a3d6 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java @@ -35,4 +35,9 @@ public @interface ApiAbility { * 指定接口是否需要授权才能访问,可在admin中进行修改 */ boolean permission() default false; + + /** + * 是否需要appAuthToken,设置为true,网关端会校验token是否存在 + */ + boolean needToken() default false; } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java index a9ba2841..db9b9af8 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java @@ -25,7 +25,7 @@ public @interface ApiMapping { /** * 版本号,默认版本号是""
- * 改默认版本号:ServiceContext.getSopServerConfig().setDefaultVersion("1.0"); + * 改默认版本号:ServiceConfig.getInstance().setDefaultVersion("1.0"); */ String version() default ""; @@ -44,6 +44,11 @@ public @interface ApiMapping { */ boolean permission() default false; + /** + * 是否需要appAuthToken,设置为true,网关端会校验token是否存在 + */ + boolean needToken() default false; + // ------------ 自定义属性 end ------------ diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/OpenContext.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/OpenContext.java index 0795c0ad..b3f2d3d3 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/OpenContext.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/OpenContext.java @@ -81,12 +81,23 @@ public interface OpenContext extends OpenBeanFactory { Date getTimestamp(); /** - * 返回token,即access_token + * 返回token,即access_token. * + * @deprecated 废弃,使用getAppAuthToken() * @return 返回token */ + @Deprecated String appAuthToken(); + /** + * 返回token,即access_token + * + * @return 返回token + */ + default String getAppAuthToken() { + return appAuthToken(); + } + /** * 返回回调地址 * diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java index 3171e193..7998d941 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java @@ -28,6 +28,8 @@ public class ServiceApiInfo { private int mergeResult; /** 是否需要授权才能访问 */ private int permission; + /** 是否需要token */ + private int needToken; /** 是否是原始Mapping */ private boolean originalMapping; diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java index a7fc4ca7..215db872 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ApiMetaBuilder.java @@ -87,6 +87,7 @@ public class ApiMetaBuilder { apiMeta.setIgnoreValidate(BooleanUtils.toInteger(apiMappingInfo.isIgnoreValidate())); apiMeta.setMergeResult(BooleanUtils.toInteger(apiMappingInfo.isMergeResult())); apiMeta.setPermission(BooleanUtils.toInteger(apiMappingInfo.isPermission())); + apiMeta.setNeedToken(BooleanUtils.toInteger(apiMappingInfo.isNeedToken())); return apiMeta; } else { if (!ServiceContext.getCurrentContext().getBoolean(ServiceContext.RESTFUL_KEY, false)) { diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java index b85f32f4..bda9ba59 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java @@ -50,8 +50,8 @@ public class ServiceRouteInfoBuilder { List apis = serviceApiInfo.getApis(); List routeDefinitionList = new ArrayList<>(apis.size()); for (ServiceApiInfo.ApiMeta apiMeta : apis) { - RouteDefinition gatewayRouteDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, apiMeta); - routeDefinitionList.add(gatewayRouteDefinition); + RouteDefinition routeDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, apiMeta); + routeDefinitionList.add(routeDefinition); } ServiceRouteInfo serviceRouteInfo = new ServiceRouteInfo(); serviceRouteInfo.setServiceId(serviceApiInfo.getServiceId()); diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java index 9ae43b00..506704b6 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java @@ -35,9 +35,10 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple method.setAccessible(true); String name = null; String version; - boolean ignoreValidate = false; - boolean mergeResult = true; - boolean permission = false; + boolean ignoreValidate; + boolean mergeResult; + boolean permission; + boolean needToken = false; ApiMapping apiMapping = method.getAnnotation(ApiMapping.class); if (apiMapping != null) { name = apiMapping.value()[0]; @@ -45,6 +46,7 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple ignoreValidate = apiMapping.ignoreValidate(); mergeResult = apiMapping.mergeResult(); permission = apiMapping.permission(); + needToken = apiMapping.needToken(); } else { ApiAbility apiAbility = this.findApiAbilityAnnotation(method); if (apiAbility != null) { @@ -52,6 +54,7 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple ignoreValidate = apiAbility.ignoreValidate(); mergeResult = apiAbility.mergeResult(); permission = apiAbility.permission(); + needToken = apiAbility.needToken(); } else { return super.getCustomMethodCondition(method); } @@ -75,6 +78,7 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple apiMappingInfo.setIgnoreValidate(ignoreValidate); apiMappingInfo.setMergeResult(mergeResult); apiMappingInfo.setPermission(permission); + apiMappingInfo.setNeedToken(needToken); logger.info("注册接口,name:" + method + ", version:" + version); return new ApiMappingRequestCondition(apiMappingInfo); } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java index f04248ef..cc2dfb3d 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java @@ -12,6 +12,7 @@ public class ApiMappingInfo { private boolean ignoreValidate; private boolean mergeResult; private boolean permission; + private boolean needToken; public ApiMappingInfo(String name, String version) { this.name = name; diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/RouteDefinition.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/RouteDefinition.java index 5cd8a343..265771c0 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/RouteDefinition.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/RouteDefinition.java @@ -68,4 +68,9 @@ public class RouteDefinition { * 是否需要授权才能访问 */ private int permission; + + /** + * 是否需要token + */ + private int needToken; } \ No newline at end of file diff --git a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/TokenController.java b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/TokenController.java new file mode 100644 index 00000000..f0da8211 --- /dev/null +++ b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/TokenController.java @@ -0,0 +1,28 @@ +package com.gitee.sop.storyweb.controller; + +import com.gitee.sop.servercommon.annotation.ApiMapping; +import com.gitee.sop.servercommon.bean.OpenContext; +import com.gitee.sop.servercommon.bean.ServiceContext; +import com.gitee.sop.storyweb.controller.param.StoryParam; +import com.gitee.sop.storyweb.controller.result.StoryResult; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author tanghc + */ +@RestController +@Slf4j +@Api(tags = "故事接口") +public class TokenController { + + @ApiMapping(value = "story.token.get", needToken = true/* 设置true,网关会校验token是否存在 */) + public StoryResult token(StoryParam story) { + OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext(); + String appAuthToken = openContext.getAppAuthToken(); + StoryResult result = new StoryResult(); + result.setName("appAuthToken:" + appAuthToken); + return result; + } +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigServiceRoute.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigServiceRoute.java index d063844b..dbed6fa8 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigServiceRoute.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigServiceRoute.java @@ -1,15 +1,13 @@ package com.gitee.sop.gateway.entity; -import com.gitee.fastmybatis.core.annotation.LogicDelete; import lombok.Data; -import java.util.Date; - import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import java.util.Date; /** @@ -63,6 +61,9 @@ public class ConfigServiceRoute { /** 是否需要授权才能访问, 数据库字段:permission */ private Byte permission; + /** 是否需要token, 数据库字段:need_token */ + private Byte needToken; + /** 数据库字段:gmt_create */ private Date gmtCreate; diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRoutesProcessor.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRoutesProcessor.java index beab446e..5295c89e 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRoutesProcessor.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/manager/DbRoutesProcessor.java @@ -54,6 +54,7 @@ public class DbRoutesProcessor implements RoutesProcessor { configServiceRoute.setStatus((byte) routeDefinition.getStatus()); configServiceRoute.setPermission((byte) routeDefinition.getPermission()); configServiceRoute.setOrder(routeDefinition.getOrder()); + configServiceRoute.setNeedToken((byte)routeDefinition.getNeedToken()); configServiceRoute.setServiceId(serviceId); return configServiceRoute; }) diff --git a/sop-test/src/main/java/com/gitee/sop/test/Client.java b/sop-test/src/main/java/com/gitee/sop/test/Client.java index a4c9e5a7..398996c7 100644 --- a/sop-test/src/main/java/com/gitee/sop/test/Client.java +++ b/sop-test/src/main/java/com/gitee/sop/test/Client.java @@ -138,6 +138,7 @@ public class Client { private Map header; private boolean ignoreSign; private boolean postJson; + private String appAuthToken; private List uploadFileList; private Callback callback; @@ -229,6 +230,17 @@ public class Client { return this; } + /** + * 设置token + * + * @param appAuthToken 给定的token + * @return 返回RequestBuilder + */ + public RequestBuilder appAuthToken(String appAuthToken) { + this.appAuthToken = appAuthToken; + return this; + } + /** * 添加文件 * @@ -310,6 +322,9 @@ public class Client { if (version != null) { params.put("version", version); } + if (appAuthToken != null) { + params.put("app_auth_token", appAuthToken); + } params.put("format", "json"); params.put("charset", "utf-8"); params.put("sign_type", "RSA2"); diff --git a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java index 375734d6..793725c8 100644 --- a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java +++ b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java @@ -287,6 +287,17 @@ public class AllInOneTest extends TestBase { System.out.println("成功次数:" + success); } + public void testToken() { + Client.RequestBuilder requestBuilder = new Client.RequestBuilder() + .method("story.token.get") + .version("1.0") + .bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")) + .appAuthToken("asdfasdfadsf") + .httpMethod(HttpTool.HTTPMethod.GET); + + client.execute(requestBuilder); + } + class BizContent extends HashMap { public BizContent add(String key, String value) { this.put(key, value);