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; }
好啦,赶快去试一下吧!