mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-07 17:38:38 +08:00
commit
9d4eceeda0
@ -2,6 +2,7 @@ package org.dromara.sms4j.tencent.service;
|
|||||||
|
|
||||||
import cn.hutool.json.JSONArray;
|
import cn.hutool.json.JSONArray;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.jdcloud.sdk.utils.StringUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.sms4j.api.AbstractSmsBlend;
|
import org.dromara.sms4j.api.AbstractSmsBlend;
|
||||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||||
@ -97,10 +98,16 @@ public class TencentSmsImpl extends AbstractSmsBlend {
|
|||||||
.onSuccess(((data, req, res) -> {
|
.onSuccess(((data, req, res) -> {
|
||||||
JSONObject jsonBody = res.get(JSONObject.class);
|
JSONObject jsonBody = res.get(JSONObject.class);
|
||||||
JSONObject response = jsonBody.getJSONObject("Response");
|
JSONObject response = jsonBody.getJSONObject("Response");
|
||||||
|
String error = response.getStr("Error");
|
||||||
|
if (StringUtils.isNotBlank(error)){
|
||||||
|
smsResponse.setErrorCode("500");
|
||||||
|
smsResponse.setErrMessage(error);
|
||||||
|
}else {
|
||||||
JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
|
JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
|
||||||
smsResponse.setBizId(sendStatusSet.getJSONObject(0).getStr("SerialNo"));
|
smsResponse.setBizId(sendStatusSet.getJSONObject(0).getStr("SerialNo"));
|
||||||
smsResponse.setMessage(sendStatusSet.getJSONObject(0).getStr("Message"));
|
smsResponse.setMessage(sendStatusSet.getJSONObject(0).getStr("Message"));
|
||||||
smsResponse.setCode(sendStatusSet.getJSONObject(0).getStr("Code"));
|
smsResponse.setCode(sendStatusSet.getJSONObject(0).getStr("Code"));
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
.onError((ex, req, res) -> {
|
.onError((ex, req, res) -> {
|
||||||
JSONObject jsonBody = res.get(JSONObject.class);
|
JSONObject jsonBody = res.get(JSONObject.class);
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
package org.dromara.sms4j.tencent.utils;
|
package org.dromara.sms4j.tencent.utils;
|
||||||
|
|
||||||
import cn.hutool.crypto.digest.HMac;
|
import com.alibaba.fastjson.JSON;
|
||||||
import cn.hutool.crypto.digest.HmacAlgorithm;
|
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.sms4j.tencent.config.TencentConfig;
|
import org.dromara.sms4j.tencent.config.TencentConfig;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.xml.bind.DatatypeConverter;
|
import javax.xml.bind.DatatypeConverter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
@ -34,9 +34,11 @@ public class TencentUtils {
|
|||||||
private static final String CT_JSON = "application/json; charset=utf-8";
|
private static final String CT_JSON = "application/json; charset=utf-8";
|
||||||
|
|
||||||
|
|
||||||
private static byte[] hmac256(byte[] key, String msg) {
|
private static byte[] hmac256(byte[] key, String msg) throws Exception {
|
||||||
HMac hMac = new HMac(HmacAlgorithm.HmacSHA256, key);
|
Mac mac = Mac.getInstance("HmacSHA256");
|
||||||
return hMac.digest(msg.getBytes(StandardCharsets.UTF_8));
|
SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
|
||||||
|
mac.init(secretKeySpec);
|
||||||
|
return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String sha256Hex(String s) throws Exception {
|
private static String sha256Hex(String s) throws Exception {
|
||||||
@ -56,37 +58,30 @@ public class TencentUtils {
|
|||||||
*/
|
*/
|
||||||
public static String generateSignature(TencentConfig tencentConfig, String templateId, String[] messages, String[] phones,
|
public static String generateSignature(TencentConfig tencentConfig, String templateId, String[] messages, String[] phones,
|
||||||
String timestamp) throws Exception {
|
String timestamp) throws Exception {
|
||||||
// ************* 步骤 1:拼接规范请求串 *************
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
String date = sdf.format(new Date(Long.parseLong(timestamp + "000")));
|
String date = sdf.format(new Date(Long.parseLong(timestamp + "000")));
|
||||||
String canonicalUri = "/";
|
String canonicalUri = "/";
|
||||||
String canonicalQueryString = "";
|
String canonicalQueryString = "";
|
||||||
String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + tencentConfig.getRequestUrl() + "\n";
|
String canonicalHeaders = "content-type:application/json; charset=utf-8\nhost:" + tencentConfig.getRequestUrl() + "\n";
|
||||||
String signedHeaders = "content-type;host";
|
String signedHeaders = "content-type;host";
|
||||||
HashMap<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
// 实际调用需要更新参数,这里仅作为演示签名验证通过的例子
|
|
||||||
params.put("PhoneNumberSet", phones);
|
params.put("PhoneNumberSet", phones);
|
||||||
params.put("SmsSdkAppId", tencentConfig.getSdkAppId());
|
params.put("SmsSdkAppId", tencentConfig.getSdkAppId());
|
||||||
params.put("SignName", tencentConfig.getSignature());
|
params.put("SignName", tencentConfig.getSignature());
|
||||||
params.put("TemplateId", templateId);
|
params.put("TemplateId", templateId);
|
||||||
params.put("TemplateParamSet", messages);
|
params.put("TemplateParamSet", messages);
|
||||||
String payload = JSONUtil.toJsonStr(params);
|
String payload = JSON.toJSONString(params);
|
||||||
String hashedRequestPayload = sha256Hex(payload);
|
String hashedRequestPayload = sha256Hex(payload);
|
||||||
String canonicalRequest = HTTP_REQUEST_METHOD + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
|
String canonicalRequest = HTTP_REQUEST_METHOD + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
|
||||||
+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
|
String credentialScope = date + "/" + tencentConfig.getService() + "/tc3_request";
|
||||||
// ************* 步骤 2:拼接待签名字符串 *************
|
|
||||||
String credentialScope = date + "/" + tencentConfig.getService() + "/" + "tc3_request";
|
|
||||||
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
|
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
|
||||||
String stringToSign = ALGORITHM + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
|
String stringToSign = ALGORITHM + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
|
||||||
// ************* 步骤 3:计算签名 *************
|
|
||||||
byte[] secretDate = hmac256(("TC3" + tencentConfig.getAccessKeySecret()).getBytes(StandardCharsets.UTF_8), date);
|
byte[] secretDate = hmac256(("TC3" + tencentConfig.getAccessKeySecret()).getBytes(StandardCharsets.UTF_8), date);
|
||||||
byte[] secretService = hmac256(secretDate, tencentConfig.getService());
|
byte[] secretService = hmac256(secretDate, tencentConfig.getService());
|
||||||
byte[] secretSigning = hmac256(secretService, "tc3_request");
|
byte[] secretSigning = hmac256(secretService, "tc3_request");
|
||||||
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
|
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
|
||||||
// ************* 步骤 4:拼接 Authorization *************
|
return ALGORITHM + " Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", SignedHeaders=" + signedHeaders + ", Signature=" + signature;
|
||||||
return ALGORITHM + " " + "Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", "
|
|
||||||
+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user