编程语言Java接口签名(Signature)实现方案
    
   
    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 parms=new TreeMap<>();
        parms.put(appkey,headerAppkey);
        parms.put(timestamp,headerTimestamp);
        parms.put(noncestr,headerNoncestr);
        Map stringObjectMap = objectToMap(parms, preInfoItem);
        String s = buildSignature(stringObjectMap);
        //签名比对
        if (s.equals(headerSignature)){
            return true;
        }
        return false;
    }
    Map objectToMap(Map 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 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;
    }
好啦,赶快去试一下吧!
文章来源:https://www.cnblogs.com/tianClassmate/p/15819039.html
 
