Skip to content

HTTP 接口签名(防篡改) ​

yudao-spring-boot-starter-protection 技术组件,由它的 signature 包,提供 HTTP 接口签名特性,提高安全性。 例如说:项目给第三方提供 HTTP 接口时,为了提高对接中数据传输的安全性(防止请求参数被篡改),同时校验调用方的有效性,通常都需要增加签名 sign。 市面上也有非常多的案例,例如说:

# 1. 实现原理 ​

在 Controller 的方法上,添加 @ApiSignature 注解,声明它需要签名。 然后,通过 AOP 切面,ApiSignatureAspect 对这些方法进行拦截,校验签名是否正确。它的签名算法如下: // ApiSignatureAspect.java String serverSignatureString = buildSignatureString(signature, request, appSecret) DigestUtil.sha256Hex(serverSignatureString); private String buildSignatureString(ApiSignature signature, HttpServletRequest request, String appSecret) { SortedMap parameterMap = getRequestParameterMap(request); // 请求头 SortedMap headerMap = getRequestHeaderMap(signature, request); // 请求参数 String requestBody = StrUtil.nullToDefault(ServletUtils.getBody(request), ""); // 请求体 return MapUtil.join(parameterMap, "&", "=")

  • requestBody
  • MapUtil.join(headerMap, "&", "=")
  • appSecret; } ① 将请求头、请求体、请求参数,按照一定顺序排列,然后添加密钥,获得需要进行签名的字符串。 其中,每个调用方 appId 对应一个唯一 appSecret,通过在 Redis 配置,它对应 key 为 api_signature_app 的 HASH 结构,hashKey 为 appId。 ② 之后,通过 SHA256 进行加密,得到签名 sign。 注意:第三方调用时,每次请求 Header 需要带上 appId、timestamp、nonce、sign 四个参数:
  • appId:调用方的唯一标识。
  • timestamp:请求时的时间戳。
  • nonce:用于请求的防重放攻击,每次请求唯一,例如说 UUID。
  • sign:HTTP 签名。 疑问:为什么使用请求 Header 传参? 避免这四个参数,在请求 QueryString、Request Body 可能重复的问题!

# 2. 使用示例 ​

① 在需要使用的 yudao-module-xxx 模块的 ,引入 yudao-spring-boot-starter-protection 依赖: cn.iocoder.boot yudao-spring-boot-starter-protection ② 在 Redis 添加一个 appId 为 test,密钥为 123456 的配置: hset api_signature_app test 123456 ③ 在 Controller 的方法上,添加 @ApiSignature 注解: // UserController.java @GetMapping("/page") @Operation(summary = "获得用户分页列表") @PreAuthorize("@ss.hasPermission('system:user:list')") @ApiSignature(timeout = 30, timeUnit = TimeUnit.MINUTES) // 关键是此处。ps:设置为 30 分钟,只是为了测试方便,不是必须! public CommonResult> getUserPage(@Valid UserPageReqVO pageReqVO) { // ... 省略代码 } ④ 调用该 API 接口,执行成功。如下是一个 IDEA HTTP 的示例: // UserController.http GET /system/user/page?pageNo=1&pageSize=10 Authorization: Bearer appId: test timestamp: 1717494535932 nonce: e7eb4265-885d-40eb-ace3-2ecfc34bd639 sign: 01e1c3df4d93eafc862753641ebfc1637e70f853733684a139f8b630af5c84cd tenant-id:

  • appId、timestamp、nonce、sign 通过请求 Header 传递,避免和请求参数冲突。【必须传递】
  • timestamp:请求时的时间戳。
  • nonce:用于请求的防重放攻击,每次请求唯一,例如说 UUID。
  • sign:HTTP 签名。如果你不知道多少,可以直接 debug ApiSignatureAspect 的 serverSignature 处的代码,进行获得。 友情提示:强烈建议 ApiSignatureAspect 的实现代码,一共就 100 多行代码。可以通过 ApiSignatureTest 单元测试,直接执行噢! .pageB img{width:80px!important;} .wwads-horizontal .wwads-text, .wwads-content .wwads-text{line-height:1;} 请求限流(RateLimiter) HTTP 接口加解密 ← 请求限流(RateLimiter) HTTP 接口加解密→ Theme by Vdoing | Copyright © 2019-2026 芋道源码 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式 × .windowRB{ padding: 0;} .windowRB .wwads-img{margin-top: 10px;} .windowRB .wwads-content{margin: 0 10px 10px 10px;} .custom-html-window-rb .close-but{ display: none; }
最近更新