Java接口签名(Signature)实现计划

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

今天上午收到一个需要,针对以后的零碎开发一个对外开放的接口。

既然是对外开放,那么调用者肯定没有咱们零碎的Token,就须要对调用者进行签名验证,签名验证采纳支流的验证形式,采纳Signature 的形式。

一、要求

下图为具体要求

二、流程

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

  2、退出timestamp(工夫戳),10分钟内数据无效

  3、退出流水号noncestr(避免反复提交),至多为10位。针对查问接口,流水号只用于日志落地,便于前期日志核查。 针对办理类接口需校验流水号在有效期内的唯一性,以防止反复申请。

  4、退出signature,所有数据的签名信息。

三、实现

简略来说,调用者调用接口业务参数在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;    }

好啦,赶快去试一下吧!