基于APPKEY和APPSECRET的授权验证
为了避免对接方多一次登录授权获取 token ,升级了第三方接入接口。由原来的登录获取 token ,每次请求携带 token 获取数据变更为:appkey 和 appsecret 的方式。
直接上干货,自己捞。(Java 签名工具类)
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Formatter;
import java.util.List;
/**
* 签名助手
*
* @author Ryan
* @date 2019/9/3 9:48
*/
public class SignatureHelper {
private static final Logger log = LoggerFactory.getLogger(SignatureHelper.class);
private static final String HASH_ALGORITHM = "HmacSHA256";
/**
* @return
*/
public static synchronized String nonce() {
return RandomStringUtils.randomAlphanumeric(8);
}
/**
* @param timestamp
* @param nonce
* @param apiKey
* @return
*/
public static String generateJoinStr(String timestamp, String nonce, String apiKey) {
List<String> beforesort = new ArrayList<String>(3);
beforesort.add(apiKey);
beforesort.add(timestamp);
beforesort.add(nonce);
// 排序
beforesort.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
try {
String s1 = new String(o1.toString().getBytes("GB2312"), "ISO-8859-1");
String s2 = new String(o2.toString().getBytes("GB2312"), "ISO-8859-1");
return s1.compareTo(s2);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
});
StringBuilder aftersort = new StringBuilder();
for (int i = 0; i < beforesort.size(); i++) {
aftersort.append(beforesort.get(i));
}
return aftersort.toString();
}
/**
* @param appKey
* @param appSecret
* @return
*/
private static String genEncryptString(String appKey, String appSecret) throws NoSuchAlgorithmException, InvalidKeyException {
Key secretKey = new SecretKeySpec(appSecret.getBytes(), HASH_ALGORITHM);
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
//完成hamc-sha256签名
final byte[] hmac = mac.doFinal(appKey.getBytes());
StringBuilder sb = new StringBuilder(hmac.length * 2);
Formatter formatter = new Formatter(sb);
for (byte b : hmac) {
formatter.format("%02x", b);
}
//完成16进制编码
return sb.toString();
}
/**
* @param apiKey
* @param timestamp
* @param nonce
* @param signature
* @return
*/
public static String sign(String apiKey, String timestamp, String nonce, String signature) {
return String.format("appkey=%s,timestamp=%s,nonceStr=%s,sign=%s", apiKey, timestamp, nonce, signature);
}
/**
* @param apiKey
* @param appSecret
* @return
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
*/
public static String token(String apiKey, String timestamp, String nonce, String appSecret) throws InvalidKeyException, NoSuchAlgorithmException {
String genjoinstr = generateJoinStr(timestamp, nonce, apiKey);
String signature = genEncryptString(genjoinstr, appSecret);
String sign = sign(apiKey, timestamp, nonce, signature);
return DigestUtils.md5Hex(sign);
}
/**
* @param appkey
* @param timestamp
* @param nonce
* @param token
* @return
*/
public static boolean matchSign(String appkey, String appSecret, String timestamp, String nonce, String token) {
try {
String t = token(appkey, timestamp, nonce, appSecret);
return token.equals(t);
} catch (InvalidKeyException e) {
log.error("InvalidKeyException", e);
} catch (NoSuchAlgorithmException e) {
log.error("NoSuchAlgorithmException", e);
}
return false;
}
/**
* @param apiKey
* @return
*/
public static String genauthorization(String apiKey, String appSecret) throws InvalidKeyException, NoSuchAlgorithmException {
String nonce = nonce();
String timestamp = Long.toString(System.currentTimeMillis());
String genjoinstr = generateJoinStr(timestamp, nonce, apiKey);
String signature = genEncryptString(genjoinstr, appSecret);
return "appkey=" + apiKey + ",timestamp=" + timestamp + ",nonce=" + nonce + ",sign=" + signature;
}
}
为了方便测试,写个 postman ,记录一下信息:
/**
* datetime 2020年7月21日 11:10
* author Ryan
* description 授权 Header 管理;
*/
var appKey = "depot_4f34ft4rej76k6j3395072"
var appSecret="7RL2pPavM8E2f9ctM4DNq6uXCFueuJ6X"
pm.globals.unset("appkey");
pm.globals.unset("nonceStr");
pm.globals.unset("token");
pm.globals.unset("timestamp");
/** ************************************************************************************************************************* */
//生成随机字符串
function randomString(len) {
len = len || 32;
var $chars = "ABCDEFGHJKMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz23456789";
var maxLen = $chars.length;
var str = "";
for (i = 0; i < len; i++) {
str += $chars.charAt(Math.floor(Math.random() * maxLen));
}
return str;
}
var nonceStr = randomString(8);
var timestamp = new Date().getTime() + "";
var joinStr = [appKey, nonceStr, timestamp];
var generateJoinStr = joinStr.sort((a, b) => a.localeCompare(b)).join("");
var hmacSHA256 = CryptoJS.HmacSHA256(generateJoinStr, appSecret);
var signature =hmacSHA256.toString(CryptoJS.enc.Hex)
var sign = "appkey=" + appKey + ",timestamp=" + timestamp + ",nonceStr="+nonceStr + ",sign=" +signature;
var token = CryptoJS.MD5(sign) + "";
pm.globals.set("appkey", appKey);
pm.globals.set("nonceStr", nonceStr);
pm.globals.set("token", token);
pm.globals.set("timestamp", timestamp);
console.log("========================================================================================================");
console.log("appkey=" + appKey);
console.log("appSecret=" + appSecret);
console.log("nonceStr=" + nonceStr);
console.log("timestamp=" + timestamp);
console.log("generateJoinStr=" + generateJoinStr);
console.log("sign=" + sign);
console.log("token : " + token);
(注意: postman 的 pre-request script 在做加密的时候,偶尔会出现加密数据不稳定的情况,原因暂且没有定位到,待定位到后再更新。
以上是 基于APPKEY和APPSECRET的授权验证 的全部内容, 来源链接: utcz.com/z/518728.html