继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Java接口签名(Signature)实现方案

程序员田同学
关注TA
已关注
手记 27
粉丝 1
获赞 9

Java接口签名(Signature)实现方案

大家好,我是程序员田同学!

今天上午收到一个需求,针对当前的系统开发一个对外开放的接口。

既然是对外开放,那么调用者一定没有我们系统的Token,就需要对调用者进行签名验证,签名验证采用主流的验证方式,采用Signature 的方式。

一、要求

下图为具体要求

image-20220118171527945

二、流程

1、线下分配appid和appsecret,针对不同的调用方分配不同的appid和appsecret

2、加入timestamp(时间戳),10分钟内数据有效

3、加入流水号noncestr(防止重复提交),至少为10位。针对查询接口,流水号只用于日志落地,便于后期日志核查。 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。

4、加入signature,所有数据的签名信息。

image-20220118171245456

三、实现

简单来说,调用者调用接口业务参数在body中传递,header中额外增加四个参数signature、appkey、timestamp、noncestr。

我们在后台取到四个参数,其后三个参数加上调用者分配的appSecret,使用字典排序并使用MD5加密后与第一个参数signature进行比对,一致既表示调用者有权限调用。

以下代码为接口验证签名的demo实现:

//引用jackson依赖
@Autowired
private ObjectMapper objectMapper;

@Value("${appsecret}")
private String appSecret;

/**

  • 验证签名
  • @param preInfoItem
  • @return
    */
    boolean checkSignature(PreInfoItem preInfoItem) throws JsonProcessingException, IllegalAccessException {

    String signature=“signature”;

    String appkey=“appkey”;

    String timestamp=“timestamp”;

    String noncestr=“noncestr”;

    HttpServletRequest request = ServletUtils.getRequest();

    String headerSignature = request.getHeader(signature);
    String headerAppkey = request.getHeader(appkey);
    String headerTimestamp = request.getHeader(timestamp);
    String headerNoncestr = request.getHeader(noncestr);

    //因为需要排序,直接使用TreeMap
    Map<String,Object> parms=new TreeMap<>();
    parms.put(appkey,headerAppkey);
    parms.put(timestamp,headerTimestamp);
    parms.put(noncestr,headerNoncestr);


    Map<String, Object> stringObjectMap = objectToMap(parms, preInfoItem);
    String s = buildSignature(stringObjectMap);
    //签名比对
    if (s.equals(headerSignature)){
    return true;
    }
    return false;
    }

    Map<String,Object> objectToMap(Map<String,Object> map,Object o){
    Field[] declaredFields = o.getClass().getDeclaredFields();

    for (Field field : declaredFields) {
    field.setAccessible(true);

    try {
    if (field.getName() instanceof String){
    map.put(field.getName(),field.get(o));
    }
    }catch (IllegalAccessException e){
    throw new CustomException(“对象转map异常”);
    }

    }
    return map;
    }

    private String buildSignature(Map<String,Object> maps){
    String s2;
    try {
    StringBuffer s = null;
    String s1 = objectMapper.writeValueAsString(maps);
    //添加appSecret
    s.append(s1).append(appSecret);
    s2 = DigestUtils.md5DigestAsHex(s.toString().getBytes());
    }catch (JsonProcessingException e){
    throw new CustomException(“map转json异常”);
    }

    return s2;
    }

好啦,赶快去试一下吧!

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP