feat(auth): 新增接口签名校验与退出登录功能
This commit is contained in:
74
src/main/java/com/yolo/keyborad/utils/SignUtils.java
Normal file
74
src/main/java/com/yolo/keyborad/utils/SignUtils.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package com.yolo.keyborad.utils;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class SignUtils {
|
||||
|
||||
private static final String HMAC_SHA256 = "HmacSHA256";
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
* @param params 参与签名的参数(不含 sign 本身)
|
||||
* @param secret 密钥
|
||||
*/
|
||||
public static String sign(Map<String, String> params, String secret) {
|
||||
// 1. 过滤掉空值和 sign 本身
|
||||
Map<String, String> filtered = params.entrySet().stream()
|
||||
.filter(e -> e.getValue() != null && !"sign".equalsIgnoreCase(e.getKey()))
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
Map.Entry::getValue
|
||||
));
|
||||
|
||||
// 2. 按 key 字典序排序
|
||||
Map<String, String> sorted = new TreeMap<>(filtered);
|
||||
|
||||
// 3. 拼接成 key=value&key2=value2...&secret=xxx
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sorted.forEach((k, v) -> {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(k).append("=").append(urlEncode(v));
|
||||
});
|
||||
sb.append("&secret=").append(urlEncode(secret));
|
||||
|
||||
String data = sb.toString();
|
||||
return hmacSha256(data, secret);
|
||||
}
|
||||
|
||||
private static String hmacSha256(String data, String secret) {
|
||||
try {
|
||||
Mac mac = Mac.getInstance(HMAC_SHA256);
|
||||
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), HMAC_SHA256);
|
||||
mac.init(secretKey);
|
||||
byte[] bytes = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
||||
// 转十六进制小写
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
String hex = Integer.toHexString(b & 0xff);
|
||||
if (hex.length() == 1) {
|
||||
sb.append("0");
|
||||
}
|
||||
sb.append(hex);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Sign error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String urlEncode(String str) {
|
||||
try {
|
||||
return URLEncoder.encode(str, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user