对外
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -35,6 +35,12 @@
|
|||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>spring-webmvc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
|
<artifactId>okhttp</artifactId>
|
||||||
|
<version>4.11.0</version> <!-- 请根据需要选择最新版本 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
package com.yxt.ss.gateway.api.rest;
|
package com.yxt.ss.gateway.api.rest;
|
||||||
|
|
||||||
import com.yxt.ss.gateway.api.utils.ResultBean;
|
import com.yxt.ss.gateway.api.utils.ResultBean;
|
||||||
|
import com.yxt.ss.gateway.api.utils.SignatureQuery;
|
||||||
import com.yxt.ss.gateway.api.utils.SignatureUtil;
|
import com.yxt.ss.gateway.api.utils.SignatureUtil;
|
||||||
|
import okhttp3.*;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:
|
* @description:
|
||||||
@@ -30,10 +36,102 @@ public class Signature {
|
|||||||
|
|
||||||
//获取签名
|
//获取签名
|
||||||
@PostMapping("/getSign")
|
@PostMapping("/getSign")
|
||||||
ResultBean<String> getSign(@RequestParam("parameters") Map<String, String> parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
ResultBean<String> getSign(SignatureQuery query) {
|
||||||
ResultBean<String> rb = ResultBean.fireFail();
|
ResultBean<String> rb = ResultBean.fireFail();
|
||||||
|
try {
|
||||||
|
Map<String, String> formData = new HashMap<>();
|
||||||
|
Map<String, String> map = query.getParameters();
|
||||||
|
formData.put("key1", map.getOrDefault("key1", "").toString());
|
||||||
|
String appKey = query.getAppKey();
|
||||||
|
String secret = query.getSecret();
|
||||||
|
|
||||||
|
// 生成签名
|
||||||
|
String sign = SignatureUtil.generateSignature(formData, appKey, secret);
|
||||||
|
return rb.success().setData(sign);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
return rb.setMsg("Unsupported encoding: " + e.getMessage());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
return rb.setMsg("Algorithm not found: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(10, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(10, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建URL
|
||||||
|
String endPoint = "http://127.0.0.1:9999";
|
||||||
|
String path = "/signature/getSign";
|
||||||
|
|
||||||
|
// 假设data是一个包含所有参数的字典
|
||||||
|
Map<String, String> data = new HashMap<>();
|
||||||
|
data.put("parameters[key1]", "value1");
|
||||||
|
data.put("parameters[key2]", "value2");
|
||||||
|
data.put("appKey", "testAppKey");
|
||||||
|
data.put("secret", "testSecret");
|
||||||
|
|
||||||
|
// 创建FormData
|
||||||
|
FormBody.Builder formBuilder = new FormBody.Builder();
|
||||||
|
for (Map.Entry<String, String> entry : data.entrySet()) {
|
||||||
|
formBuilder.add(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
RequestBody formBody = formBuilder.build();
|
||||||
|
|
||||||
|
// 构建POST请求
|
||||||
|
String url = endPoint + path;
|
||||||
|
System.out.println("Request URL: " + url);
|
||||||
|
System.out.println("Request Data: " + data);
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.post(formBody)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
System.out.println("Response: " + response.body().string());
|
||||||
|
} else {
|
||||||
|
System.err.println("Request failed: " + response.code());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Network error: " + e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Unexpected error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取签名
|
||||||
|
@PostMapping("/getSign2")
|
||||||
|
ResultBean<String> getSign2(@RequestParam("parameters") Map<String, String> parameters,
|
||||||
|
@RequestParam("appKey") String appKey,
|
||||||
|
@RequestParam("secret") String secret) {
|
||||||
|
ResultBean<String> rb = ResultBean.fireFail();
|
||||||
|
try {
|
||||||
|
// 1. 参数校验
|
||||||
|
if (parameters == null || parameters.isEmpty()) {
|
||||||
|
return rb.setMsg("Parameters cannot be empty.");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(appKey)) {
|
||||||
|
return rb.setMsg("AppKey cannot be empty.");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(secret)) {
|
||||||
|
return rb.setMsg("Secret cannot be empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成签名
|
||||||
String sign = SignatureUtil.generateSignature(parameters, appKey, secret);
|
String sign = SignatureUtil.generateSignature(parameters, appKey, secret);
|
||||||
return rb.success().setData(sign);
|
return rb.success().setData(sign);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
return rb.setMsg("Unsupported encoding: " + e.getMessage());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
return rb.setMsg("Algorithm not found: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -42,45 +140,73 @@ public class Signature {
|
|||||||
* 返回系统参数
|
* 返回系统参数
|
||||||
*/
|
*/
|
||||||
@PostMapping("/getSignParameters")
|
@PostMapping("/getSignParameters")
|
||||||
public ResultBean<Map<String, String>> signParameters(@RequestParam("parameters") Map<String, String> parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
public ResultBean<Map<String, String>> signParameters(SignatureQuery query) {
|
||||||
ResultBean<Map<String, String>> rb = ResultBean.fireFail();
|
ResultBean<Map<String, String>> rb = ResultBean.fireFail();
|
||||||
// 1. 使用 TreeMap 按照字典顺序对参数进行排序
|
|
||||||
|
try {
|
||||||
|
Map<String, String> parameters = query.getParameters();
|
||||||
|
|
||||||
|
// 2. 使用 TreeMap 按照字典顺序对参数进行排序
|
||||||
Map<String, String> tree = new TreeMap<>(parameters);
|
Map<String, String> tree = new TreeMap<>(parameters);
|
||||||
tree.put("_app", appKey);
|
tree.put("_app", query.getAppKey());
|
||||||
tree.putIfAbsent("_t", String.valueOf(System.currentTimeMillis()));
|
tree.putIfAbsent("_t", String.valueOf(System.currentTimeMillis()));
|
||||||
|
|
||||||
// 拼接参数串
|
// 3. 拼接参数串
|
||||||
String content = SignatureUtil.joinParameters(tree);
|
String content = SignatureUtil.joinParameters(tree);
|
||||||
|
|
||||||
// 将参数串前后拼上密钥
|
// 4. 将参数串前后拼接密钥
|
||||||
content = secret + content + secret;
|
content = query.getSecret() + content + query.getSecret();
|
||||||
|
|
||||||
// 计算sign值并添加到参数集合中
|
// 5. 计算 sign 值
|
||||||
String sign = SignatureUtil.md5(content);
|
String sign = SignatureUtil.md5(content);
|
||||||
|
|
||||||
|
// 6. 添加系统参数
|
||||||
tree.put("_sign", sign);
|
tree.put("_sign", sign);
|
||||||
tree.put("_s", "");
|
tree.put("_s", "");
|
||||||
|
|
||||||
return rb.success().setData(tree);
|
return rb.success().setData(tree);
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
return rb.setMsg("Encoding error: " + e.getMessage());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
return rb.setMsg("Algorithm error: " + e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return rb.setMsg("Unexpected error: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证签名是否正确
|
* 验证签名是否正确
|
||||||
*
|
*
|
||||||
* @param parameters 请求参数
|
|
||||||
* @param appKey 应用的 AppKey
|
|
||||||
* @param secret 密钥
|
|
||||||
* @param receivedSignature 请求中的签名
|
|
||||||
* @return 是否验证通过
|
* @return 是否验证通过
|
||||||
*/
|
*/
|
||||||
@PostMapping("/validateSignature")
|
@PostMapping("/validateSignature")
|
||||||
public ResultBean<Boolean> validateSignature(@RequestParam("parameters") Map<String, String> parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret, @RequestParam("receivedSignature") String receivedSignature) throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
public ResultBean<Boolean> validateSignature(SignatureQuery query) {
|
||||||
ResultBean<Boolean> rb = ResultBean.fireFail();
|
ResultBean<Boolean> rb = ResultBean.fireFail();
|
||||||
// 1. 重新生成签名
|
|
||||||
|
try {
|
||||||
|
Map<String, String> parameters = query.getParameters();
|
||||||
|
String appKey = query.getAppKey();
|
||||||
|
String secret = query.getSecret();
|
||||||
|
|
||||||
|
|
||||||
|
// 2. 重新生成签名
|
||||||
String calculatedSignature = SignatureUtil.generateSignature(parameters, appKey, secret);
|
String calculatedSignature = SignatureUtil.generateSignature(parameters, appKey, secret);
|
||||||
|
|
||||||
// 2. 比较计算出来的签名和请求中的签名
|
// 3. 使用固定时间比较方式验证签名
|
||||||
boolean validd = calculatedSignature.equals(receivedSignature);
|
boolean valid = MessageDigest.isEqual(
|
||||||
return rb.success().setData(validd);
|
calculatedSignature.getBytes("UTF-8"),
|
||||||
|
query.getReceivedSignature().getBytes("UTF-8")
|
||||||
|
);
|
||||||
|
|
||||||
|
return rb.success().setData(valid);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
return rb.setMsg("Encoding error: " + e.getMessage());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
return rb.setMsg("Algorithm error: " + e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return rb.setMsg("Unexpected error: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.yxt.ss.gateway.api.utils;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:
|
||||||
|
* @author: dimengzhe
|
||||||
|
* @date: 2024/12/7
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class SignatureQuery {
|
||||||
|
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
//业务参数
|
||||||
|
private Map<String, String> parameters = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
private String receivedSignature;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user