详解Java接口签名(Signature)实现方案
作者:程序员田同学 时间:2022-02-05 09:28:57
大家好,我是程序员田同学!
今天上午收到一个需求,针对当前的系统开发一个对外开放的接口。
既然是对外开放,那么调用者一定没有我们系统的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;
}
来源:https://www.cnblogs.com/tianClassmate/p/15819039.html
标签:Java,接口签名,Signature
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
C#中异步和多线程的区别介绍
2021-08-23 07:06:49
struts2的国际化实现网站整体中英文切换实例代码
2023-08-31 02:37:40
![](https://img.aspxhome.com/file/2023/2/70982_0s.png)
Java实现五子棋网络版
2022-05-06 04:11:29
![](https://img.aspxhome.com/file/2023/2/63382_0s.png)
Spring Cloud + Nacos + Seata整合过程(分布式事务解决方案)
2021-08-31 04:26:52
![](https://img.aspxhome.com/file/2023/4/63734_0s.png)
Mybatis使用JSONObject接收数据库查询的方法
2023-01-17 05:10:43
![](https://img.aspxhome.com/file/2023/7/62647_0s.png)
Java最简洁数据结构之冒泡排序快速理解
2023-12-01 06:31:52
![](https://img.aspxhome.com/file/2023/8/60278_0s.png)
spring boot 集成 shiro 自定义密码验证 自定义freemarker标签根据权限渲染不同页面(推荐
2023-07-28 17:39:16
springboot基于Mybatis mysql实现读写分离
2023-11-27 21:42:59
![](https://img.aspxhome.com/file/2023/5/59425_0s.png)
Java Timer使用讲解
2023-11-28 20:30:33
Java 超详细讲解类的定义方式和对象的实例化
2021-09-11 17:38:29
![](https://img.aspxhome.com/file/2023/9/70939_0s.png)
SrpingDruid数据源加密数据库密码的示例代码
2021-06-21 03:26:26
![](https://img.aspxhome.com/file/2023/1/63021_0s.png)
SpringBoot redis分布式缓存实现过程解析
2023-10-10 22:32:25
![](https://img.aspxhome.com/file/2023/1/58541_0s.png)
Java使用Freemarker页面静态化生成的实现
2022-07-24 08:48:42
![](https://img.aspxhome.com/file/2023/9/63069_0s.png)
MyBatis在SQL语句中如何获取list的大小
2021-08-15 12:09:55
深入探究Java线程的创建与构造方法
2023-05-29 22:02:45
![](https://img.aspxhome.com/file/2023/5/72315_0s.png)
Spring MVC的优点与核心接口_动力节点Java学院整理
2023-11-28 05:43:36
![](https://img.aspxhome.com/file/2023/9/60529_0s.jpg)
RabbitMQ延迟队列及消息延迟推送实现详解
2023-11-15 15:31:31
![](https://img.aspxhome.com/file/2023/1/59001_0s.png)
Java用数组实现循环队列的示例
2022-06-26 15:09:48
一文搞懂Java ScheduledExecutorService的使用
2022-11-22 14:23:35
Android WebView基础应用详解
2023-09-30 07:36:46