Merge branch 'cc_20250808_fixsign' into 'master'
兼容老的验签 See merge request hangzhou/java/custom_zxjp!146
This commit is contained in:
@@ -44,6 +44,41 @@ public class OpenSignatureUtil {
|
||||
sb.append(key).append("=").append(JSONObject.toJSONString( value)).append("&");
|
||||
});
|
||||
|
||||
// 3.2 添加固定参数(不参与排序)
|
||||
sb.append("appkey=").append(appKey)
|
||||
.append("×tamp=").append(timestamp);
|
||||
log.info("待签名字符串:{}", sb);
|
||||
// 4. 生成签名
|
||||
return hmacSha256(sb.toString(), appSecret);
|
||||
|
||||
}
|
||||
|
||||
public static String generateOldSign(Map<String, String> params, String appSecret) {
|
||||
// 1. 分离固定参数和业务参数
|
||||
String appKey = params.get("appKey");
|
||||
String timestamp = params.get("timestamp");
|
||||
|
||||
// 2. 创建不包含固定参数的临时Map用于排序
|
||||
Map<String, String> sortedParams = new TreeMap<>(
|
||||
params.entrySet().stream()
|
||||
.filter(e -> !"appKey".equals(e.getKey()))
|
||||
.filter(e -> !"timestamp".equals(e.getKey()))
|
||||
.filter(e -> !"sign".equals(e.getKey()))
|
||||
.filter(e -> e.getValue() != null && !e.getValue().isEmpty())
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
Map.Entry::getValue
|
||||
))
|
||||
);
|
||||
|
||||
// 3. 构建参数字符串:业务参数(排序后) + 固定参数
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// 3.1 添加排序后的业务参数
|
||||
sortedParams.forEach((key, value) -> {
|
||||
sb.append(key).append("=").append(value).append("&");
|
||||
});
|
||||
|
||||
// 3.2 添加固定参数(不参与排序)
|
||||
sb.append("appkey=").append(appKey)
|
||||
.append("×tamp=").append(timestamp);
|
||||
|
||||
@@ -381,6 +381,8 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
|
||||
requestMap.put("shopId", String.valueOf(shopInfoDO.getId()));
|
||||
commonService.sendMessage(new ArrayList<>(auditFranchiseFeeUsers), MessageEnum.MESSAGE_20, requestMap);
|
||||
} else if (Constants.ONE_INTEGER.equals(request.getAuditResult())) {
|
||||
log.info("合同审核,装修属性:{},加盟模式:{}",ShopDecorationAttributesEnum.getDescByCode(shopInfoDO.getShopDecorationAttributes()),
|
||||
JoinModeEnum.getByCode(shopInfoDO.getJoinMode()));
|
||||
if (shopInfoDO.getShopDecorationAttributes().equals(ShopDecorationAttributesEnum.OLD_NEW_OPEN.getCode())) {
|
||||
//老店新开时装修与开业直接完成
|
||||
shopStageInfoDAO.batchUpdateByShopIdsAndSubStageStatus(Arrays.asList(shopId), Arrays.asList(
|
||||
@@ -388,7 +390,7 @@ public class SignFranchiseServiceImpl implements SignFranchiseService, AuditResu
|
||||
));
|
||||
}else{
|
||||
//,加盟公司自有店->加盟公司建店 不推送数据 再crm中完成
|
||||
if ( !shopInfoDO.getJoinMode().equals(JoinModeEnum.FRANCHISE_COMPANIES.getCode())){
|
||||
if ( !shopInfoDO.getJoinMode().equals(JoinModeEnum.OWN_STORE.getCode())){
|
||||
hqtAPIService.pushHqtBuild(getHqtBuildRequest(request.getShopId()));
|
||||
}
|
||||
shopStageInfoDAO.updateShopStageInfo(shopId, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_861);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package com.cool.store.config;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.cool.store.constants.CommonConstants;
|
||||
import com.cool.store.enums.ErrorCodeEnum;
|
||||
@@ -7,9 +8,11 @@ import com.cool.store.response.ResponseResult;
|
||||
import com.cool.store.utils.OpenSignatureUtil;
|
||||
import com.cool.store.utils.StringUtil;
|
||||
import com.cool.store.utils.UUIDUtils;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@@ -21,9 +24,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -42,7 +43,11 @@ public class OpenApiValidateFilter implements Filter {
|
||||
private String coolAppKey;
|
||||
@Value("${cool.api.secret}")
|
||||
private String coolAppSecret;
|
||||
|
||||
// 接口映射 除了红圈通系统,云流水,新管家等使用旧的验签模式
|
||||
private static final List<String> oldUrlMapping = new ArrayList<>(Arrays.asList(
|
||||
"/zxjp/open/v1/statusRefresh","/zxjp/open/v1/changePaymentStatus",
|
||||
"/zxjp/open/v1/getYlsToken", "/zxjp/open/v1/getStoreList",
|
||||
"/zxjp/open/v1/changeReceiptStatus", "/zxjp/open/v1/getStoreUser"));
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
@@ -58,7 +63,7 @@ public class OpenApiValidateFilter implements Filter {
|
||||
}
|
||||
MDC.put(CommonConstants.REQUEST_ID, UUIDUtils.get32UUID());
|
||||
//statusRefresh 放开不需要验签
|
||||
if(uri.startsWith("/zxjp/open/v1/")||uri.startsWith("/zxjp/open/v1/getStoreUser")){
|
||||
if (uri.startsWith("/zxjp/open/v1/statusRefresh") || uri.startsWith("/zxjp/open/v1/getStoreUser")) {
|
||||
filterChain.doFilter(servletRequest, response);
|
||||
return;
|
||||
}
|
||||
@@ -120,19 +125,14 @@ public class OpenApiValidateFilter implements Filter {
|
||||
}
|
||||
|
||||
String jsonBody = requestBody.toString();
|
||||
String serverSign;
|
||||
if (oldUrlMapping.contains(uri)) {
|
||||
serverSign = getOldSign(jsonBody, appKey, timestampStr);
|
||||
} else {
|
||||
serverSign = getNewSign(jsonBody, appKey, timestampStr);
|
||||
}
|
||||
|
||||
// 2. 使用 Jackson 解析 JSON 并转为 TreeMap(自动按键排序)
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
SortedMap<String, Object> params = objectMapper.readValue(
|
||||
jsonBody,
|
||||
new TypeReference<TreeMap<String, Object>>() {}
|
||||
);
|
||||
params.put("appKey",appKey);
|
||||
params.put("timestamp", timestampStr);
|
||||
|
||||
String serverSign = OpenSignatureUtil.generateSign(params, coolAppSecret);
|
||||
|
||||
log.info("{}",serverSign);
|
||||
log.info("serverSign{}", serverSign);
|
||||
|
||||
if (!serverSign.equalsIgnoreCase(clientSign)) {
|
||||
res.setStatus(HttpStatus.OK.value());
|
||||
@@ -147,6 +147,36 @@ public class OpenApiValidateFilter implements Filter {
|
||||
}
|
||||
}
|
||||
|
||||
private @NotNull String getNewSign(String jsonBody, String appKey, String timestampStr) throws JsonProcessingException {
|
||||
// 2. 使用 Jackson 解析 JSON 并转为 TreeMap(自动按键排序)
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
SortedMap<String, Object> params = objectMapper.readValue(
|
||||
jsonBody,
|
||||
new TypeReference<TreeMap<String, Object>>() {
|
||||
}
|
||||
);
|
||||
params.put("appKey", appKey);
|
||||
params.put("timestamp", timestampStr);
|
||||
|
||||
|
||||
return OpenSignatureUtil.generateSign(params, coolAppSecret);
|
||||
}
|
||||
|
||||
private @NotNull String getOldSign(String jsonBody, String appKey, String timestampStr) throws JsonProcessingException {
|
||||
// 2. 使用 Jackson 解析 JSON 并转为 TreeMap(自动按键排序)
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
SortedMap<String, String> params = objectMapper.readValue(
|
||||
jsonBody,
|
||||
new TypeReference<TreeMap<String, String>>() {
|
||||
}
|
||||
);
|
||||
params.put("appKey", appKey);
|
||||
params.put("timestamp", timestampStr);
|
||||
|
||||
|
||||
return OpenSignatureUtil.generateOldSign(params, coolAppSecret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user