作者:Teddy (公众号:鸡仓故事汇)
再次谈起接口鉴权,大家工作中应该有遇到过给你的接口添加验证。
当我们还没有专门做第三方对接权限管理模块团队的情况下。往往是在负责人与第三方沟通下,通过一些加密算法及公钥秘钥验证直接操作的。
今天我们来介绍一个 “腾讯开放平台”的签名算法工具类
例如1:
> A:我是张三,我来查询资料。
> B:你真的是的吗?你所提供的秘钥怎么不匹配?
> A:我。。。
> // 终止资料查询
例如2:
> A:我是张三,我来查询资料。
> B:你好,张三。我已核查你的身份,请查询资料。
> A:谢谢。
> // 做自己的事情
package com.toewin.client_collection_server.util;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.digest.MD5;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 腾讯开放平台相关工具类
*
* @author My.teddy
* @date 2020-02-04 20:58
*/
public class TencentAiSignUtil {
/**
* 获取签名
*
* 签名算法
* 1. 计算步骤
* 用于计算签名的参数在不同接口之间会有差异,但算法过程固定如下4个步骤。
*
* 将请求参数对按key进行字典升序排序,得到有序的参数对列表N
* 将列表N中的参数对按URL键值对的格式拼接成字符串,得到字符串T(如:key1=value1&key2=value2),URL键值拼接过程value部分需要URL编码,URL编码算法用大写字母,例如%E8,而不是小写%e8
* 将应用密钥以app_key为键名,组成URL键值拼接到字符串T末尾,得到字符串S(如:key1=value1&key2=value2&app_key=密钥)
* 对字符串S进行MD5运算,将得到的MD5值所有字符转换成大写,得到接口请求签名
* 2. 注意事项
* 不同接口要求的参数对不一样,计算签名使用的参数对也不一样
* 参数名区分大小写,参数值为空不参与签名
* URL键值拼接过程value部分需要URL编码
* 签名有效期5分钟,需要请求接口时刻实时计算签名信息
* 更多注意事项,请查看常见问题
*
* @param map 待签名参数列表,有序({@link java.util.LinkedHashMap} 或 {@link java.util.TreeMap}),根据规则会忽略空值
* @return 签名字符串
*/
public static String getReqSign(Map<String, Object> map, String appKey) {
StringBuffer sb = new StringBuffer();
map.forEach((k, v) -> {
if (v != null && StrUtil.isNotBlank(String.valueOf(v))) {
sb.append(k).append("=").append(URLUtil.encodeAll(String.valueOf(v)).toUpperCase()).append("&");
}
});
sb.append("app_key=").append(appKey);
return MD5.create().digestHex(sb.toString()).toUpperCase();
}
//生成时间戳
public static String getTimestamp() {
long timestampLong = System.currentTimeMillis();
return String.valueOf(timestampLong);
}
public static String getNonceStr(int length){
//生成随机字符串
String str="zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
Random random=new Random();
StringBuffer randomStr=new StringBuffer();
// 设置生成字符串的长度,用于循环
for(int i=0; i<length; ++i){
//从62个的数字或字母中选择
int number=random.nextInt(62);
//将产生的数字通过length次承载到sb中
randomStr.append(str.charAt(number));
}
//将承载的字符转换成字符串
return randomStr.toString();
}
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("commodity_bar_code", "8809299231032");
// 时间戳
String timestamp = getTimestamp();
map.put("time_stamp", timestamp);
System.out.println("时间戳:" + timestamp);
// 随机数
/*String nonceStr = getNonceStr(9);
map.put("nonce_str", nonceStr);
System.out.println("随机数:" + nonceStr); */
// map.put("sign", "");
String appkey = "a95eceb1ac8c24ee28b70f7dbba912bf";
String sign = getReqSign(map, appkey);
System.out.println(sign);
}
}
ok!到这里就大功告成,小编(Teddy)在这里先感谢大家的到来。
虽然不是太详细,小编已经很努力,给小编来个一键三连(点赞,关注,收藏),小编会越来越努力。。。