Appearance
调用流程
- 任务流在调用插件时,会在构造好一切参数之后,再请求头中添加一个名为
X-Robot-Signature的参数,值为加密签名。 - 插件提供方(即各个业务方)在接收到请求时,会从请求头中获取
X-Robot-Signature参数,然后生成签名并且进行签名验证,以保证提供方接口的对外安全性。
加密规则
| 参数名 | 说明 | 位置 | 是否必填 | 示例值 |
|---|---|---|---|---|
| X-Robot-Signature | 请求签名,用于验证请求合法性 | 请求头(Header) | 是 | 4f9ef9b30d1437c6ea1f5f7ea465dd8e |
签名生成规则:
- 将请求参数按照参数名ASCII码从小到大排序
- 将排序后的参数按照"参数名=参数值"的格式拼接成字符串
- 在字符串末尾拼接上密钥(secret)
- 对最终的字符串进行MD5加密,得到32位小写签名
密钥获取方式:
加密示例
get/post的form类型
java
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class SignatureUtil {
public static void main(String[] args) throws Exception {
// 根据上方所述获取对应的密钥
String secret = "1234567890";
// 要加密的参数
Map<String, String> params = new HashMap<>();
params.put("param1", "value1");
params.put("param2", "value2");
params.put("param3", "value3");
// 生成签名
String signature = generateSignature(params, secret);
System.out.println("Signature: " + signature);
// 验证签名
boolean isValid = request.getHeader("X-Robot-Signature").equals(signature);
}
public static String generateSignature(Map<String, String> params, String secret) throws Exception {
// 按照参数名ASCII码从小到大排序
Map<String, String> sortedParams = new TreeMap<>(params);
// 将排序后的参数按照"参数名=参数值"的格式拼接成字符串 中间无需任何连字符
StringBuilder paramStr = new StringBuilder();
for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
paramStr.append(entry.getKey()).append("=").append(entry.getValue());
}
// 生成签名 上面拼接好的参数和密钥拼接在一起,然后进行MD5加密
String signature = DigestUtils.md5Hex(paramStr.toString() + secret);
return signature;
}
}post的json类型
java
@RestController
@RequestMapping("/business")
public class BusinessController {
@PostMapping("/xxxx")
public Result<String> xxxx(@RequestHeader("X-Robot-Signature") String signature, @RequestBody Map<String, Object> params) throws Exception {
// 根据上方所述获取对应的密钥
String secret = "1234567890"; // 这里是密钥,需要替换成实际的密钥
// 生成签名 上面拼接好的参数和密钥拼接在一起,然后进行MD5加密
String signature = DigestUtils.md5Hex(JSONUtil.toJsonStr(params) + secret);
if (!signature.equals(signature)) {
throw new Exception("签名验证失败");
}
// 业务逻辑处理
return Result.success("success");
}
}