项目中对接口进行签名验证的踩坑

数据准备

@RestController
@RequestMapping("/api")
@Slf4j
public class HealthController {


    @GetMapping("/health")
    public String health(@RequestBody TestVO testVO) {
        String appKey = testVO.getAppKey();
        //根据appkey找到对应的密钥
        String privateKey = getPrivateKey(appKey);
        //进行签名验证
        String requestContent = JSON.toJSONString(testVO);
        if (!checkSign(testVO.getSign(), requestContent, privateKey)) {
            return "sign check failed";
        }
        return "success";
    }

    private String getPrivateKey(String appKey) {
        //查询数据库或者缓存
        return "";
    }

    private boolean checkSign(String sign, String content, String privateKey) {
        return true;
    }

    @Data
    public static class TestVO {
        private String sign;
        private String appKey;
    }
}

问题描述

我们先将请求数据转换为我们需要的 VO 对象然后进行签名验证,后续如果 VO 变化比如增加了字段,会影响我们的验签逻辑导致失败。

解决方法

对原始请求数据进行验签

@GetMapping("/health")
public String health(@RequestBody Map<String, Object> requestData) {
    String appKey = requestData.get("appKey").toString();
    String sign = requestData.get("sign").toString();
    //根据appkey找到对应的密钥
    String privateKey = getPrivateKey(appKey);
    //进行签名验证
    String requestContent = JSON.toJSONString(requestData);
    if (!checkSign(sign, requestContent, privateKey)) {
        return "sign check failed";
    }
    return "success";
}

扩展

微信支付 SDK 中就是这种用法,先对原始数据验签,再转换为需要的 VO 对象。

image

posted @ 2025-07-04 20:14  strongmore  阅读(20)  评论(0)    收藏  举报