commit ef2e5597b32f69529ec64b9b7695b82a1c8df957 Author: dimengzhe Date: Fri Dec 6 23:20:15 2024 +0800 对外 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2a789cd --- /dev/null +++ b/pom.xml @@ -0,0 +1,72 @@ + + + + + com.yxt + yxt-parent + 0.0.1 + + + 4.0.0 + + ss-gateway-api + ss-gateway-api + 0.0.1 + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + org.projectlombok + lombok + 1.18.24 + true + + + org.springframework + spring-webmvc + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.6 + + + + repackage + + + + + + + + src/main/java + + **/*Mapper.xml + + + + src/main/resources + + **/*.* + + false + + + + + diff --git a/src/main/java/com/yxt/ss/gateway/api/GatewayApiApplication.java b/src/main/java/com/yxt/ss/gateway/api/GatewayApiApplication.java new file mode 100644 index 0000000..86b8252 --- /dev/null +++ b/src/main/java/com/yxt/ss/gateway/api/GatewayApiApplication.java @@ -0,0 +1,20 @@ +package com.yxt.ss.gateway.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @description: + * @author: dimengzhe + * @date: 2024/12/6 + **/ +//@EnableDiscoveryClient +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) +public class GatewayApiApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApiApplication.class, args); + } +} diff --git a/src/main/java/com/yxt/ss/gateway/api/rest/Signature.java b/src/main/java/com/yxt/ss/gateway/api/rest/Signature.java new file mode 100644 index 0000000..ee72d5d --- /dev/null +++ b/src/main/java/com/yxt/ss/gateway/api/rest/Signature.java @@ -0,0 +1,87 @@ +package com.yxt.ss.gateway.api.rest; + +import com.yxt.ss.gateway.api.utils.ResultBean; +import com.yxt.ss.gateway.api.utils.SignatureUtil; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.TreeMap; + +/** + * @description: + * @author: dimengzhe + * @date: 2024/12/6 + **/ +@RestController +@RequestMapping("/signature") +public class Signature { + + //appkey + static final String APPKEY = "appkey"; + //secret + static final String SECRET = "secret"; + + //获取签名 + @PostMapping("/getSign") + ResultBean getSign(@RequestParam("parameters") Map parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException { + ResultBean rb = ResultBean.fireFail(); + String sign = SignatureUtil.generateSignature(parameters, appKey, secret); + return rb.success().setData(sign); + } + + + /** + * 对传入的参数集合进行签名处理 + * 返回系统参数 + */ + @PostMapping("/getSignParameters") + public ResultBean> signParameters(@RequestParam("parameters") Map parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException { + ResultBean> rb = ResultBean.fireFail(); + // 1. 使用 TreeMap 按照字典顺序对参数进行排序 + Map tree = new TreeMap<>(parameters); + tree.put("_app", appKey); + tree.putIfAbsent("_t", String.valueOf(System.currentTimeMillis())); + + // 拼接参数串 + String content = SignatureUtil.joinParameters(tree); + + // 将参数串前后拼上密钥 + content = secret + content + secret; + + // 计算sign值并添加到参数集合中 + String sign = SignatureUtil.md5(content); + tree.put("_sign", sign); + tree.put("_s", ""); + + return rb.success().setData(tree); + } + + /** + * 验证签名是否正确 + * + * @param parameters 请求参数 + * @param appKey 应用的 AppKey + * @param secret 密钥 + * @param receivedSignature 请求中的签名 + * @return 是否验证通过 + */ + @PostMapping("/validateSignature") + public ResultBean validateSignature(@RequestParam("parameters") Map parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret, @RequestParam("receivedSignature") String receivedSignature) throws UnsupportedEncodingException, NoSuchAlgorithmException { + ResultBean rb = ResultBean.fireFail(); + // 1. 重新生成签名 + String calculatedSignature = SignatureUtil.generateSignature(parameters, appKey, secret); + + // 2. 比较计算出来的签名和请求中的签名 + boolean validd = calculatedSignature.equals(receivedSignature); + return rb.success().setData(validd); + } + + +} diff --git a/src/main/java/com/yxt/ss/gateway/api/utils/HttpStatus.java b/src/main/java/com/yxt/ss/gateway/api/utils/HttpStatus.java new file mode 100644 index 0000000..1766ccb --- /dev/null +++ b/src/main/java/com/yxt/ss/gateway/api/utils/HttpStatus.java @@ -0,0 +1,23 @@ +package com.yxt.ss.gateway.api.utils; + +/** + * @author dimengzhe + * @date 2021/6/16 10:50 + * @description + */ + +public class HttpStatus { + + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + public static final String OVERDUE = "5000"; + +} diff --git a/src/main/java/com/yxt/ss/gateway/api/utils/IResultCodeMsg.java b/src/main/java/com/yxt/ss/gateway/api/utils/IResultCodeMsg.java new file mode 100644 index 0000000..1344345 --- /dev/null +++ b/src/main/java/com/yxt/ss/gateway/api/utils/IResultCodeMsg.java @@ -0,0 +1,44 @@ +/********************************************************* + ********************************************************* + ******************** ******************* + ************* ************ + ******* _oo0oo_ ******* + *** o8888888o *** + * 88" . "88 * + * (| -_- |) * + * 0\ = /0 * + * ___/`---'\___ * + * .' \\| |// '. * + * / \\||| : |||// \ * + * / _||||| -:- |||||- \ * + * | | \\\ - /// | | * + * | \_| ''\---/'' |_/ | * + * \ .-\__ '-' ___/-. / * + * ___'. .' /--.--\ `. .'___ * + * ."" '< `.___\_<|>_/___.' >' "". * + * | | : `- \`.;`\ _ /`;.`/ - ` : | | * + * \ \ `_. \_ __\ /__ _/ .-` / / * + * =====`-.____`.___ \_____/___.-`___.-'===== * + * `=---=' * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + *********__佛祖保佑__永无BUG__验收通过__钞票多多__********* + *********************************************************/ +package com.yxt.ss.gateway.api.utils; + +/** + * Project: yxt-common
+ * File: IResultCodeMsg.java
+ * Class: com.yxt.common.core.result.IResultCodeMsg
+ * Description: <描述类的功能>.
+ * Copyright: Copyright (c) 2011
+ * Company: https://gitee.com/liuzp315
+ * Makedate: 2021/9/11 下午11:00
+ * + * @author popo + * @version 1.0 + * @since 1.0 + */ +public interface IResultCodeMsg { + String getCode(); + String getMsg(); +} diff --git a/src/main/java/com/yxt/ss/gateway/api/utils/ResultBean.java b/src/main/java/com/yxt/ss/gateway/api/utils/ResultBean.java new file mode 100644 index 0000000..23e1487 --- /dev/null +++ b/src/main/java/com/yxt/ss/gateway/api/utils/ResultBean.java @@ -0,0 +1,191 @@ +package com.yxt.ss.gateway.api.utils; + +import java.io.Serializable; + +/** + * Project: yxt-common-core
+ * File: ResultBean.java
+ * Class: com.yxt.common.core.result.ResultBean
+ * Description: 通过接口、Rest、逻辑处理执行后的结果信息.
+ * Copyright: Copyright (c) 2011
+ * Company: https://gitee.com/liuzp315
+ * Makedate: 2020/8/4 0:51
+ * + * @author liupopo + * @version 1.0 + * @since 1.0 + */ +public class ResultBean implements Serializable { + private static final long serialVersionUID = 4529658978692424234L; + + private long timestamp = System.currentTimeMillis(); + + public long getTimestamp() { + return timestamp; + } + + // 是否成功 + private boolean success; + + // 消息 返回结果的说明 + private String msg; + + // 结果状态码 + private String code; + + // 数据 + private T data; + + private String message; + + public String getMessage() { + return message; + } + + public ResultBean setMessage(String message) { + this.message = message; + return this; + } + + public ResultBean() { + } + + public ResultBean(boolean success) { + this.success = success; + } + + public ResultBean(boolean success, String msg) { + this.success = success; + this.msg = msg; + } + + public ResultBean(boolean success, String msg, String code) { + this.success = success; + this.msg = msg; + this.code = code; + } + + public ResultBean(T data) { + this.success = true; + this.data = data; + } + + public ResultBean(String code, T data) { + this.success = true; + this.code = code; + this.data = data; + } + + public ResultBean(String code, String msg, T data) { + this.success = true; + this.code = code; + this.msg = msg; + this.data = data; + } + + public boolean getSuccess() { + return success; + } + + public ResultBean setSuccess(boolean success) { + this.success = success; + return this; + } + + public String getMsg() { + return msg; + } + + public ResultBean setMsg(String msg) { + this.msg = msg; + return this; + } + + public String getCode() { + return code; + } + + public ResultBean setCode(String code) { + this.code = code; + return this; + } + + public T getData() { + return data; + } + + public ResultBean setData(T data) { + this.data = data; + return this; + } + + public ResultBean successOne() { + this.setSuccess(true); + this.setCode("0"); + this.setMessage("成功!"); + return this; + } + + public ResultBean failOne() { + this.setSuccess(false); + this.setCode(String.valueOf(HttpStatus.ERROR)); + this.setMessage("操作失败!"); + return this; + } + + public ResultBean success() { + this.setSuccess(true); + this.setCode(String.valueOf(HttpStatus.SUCCESS)); + this.setMsg("操作成功!"); + return this; + } + + public ResultBean fail() { + this.setSuccess(false); + this.setCode(String.valueOf(HttpStatus.ERROR)); + this.setMsg("操作失败!"); + return this; + } + + public static ResultBean fireSuccess() { + ResultBean rb = new ResultBean(); + rb.setSuccess(true); + rb.setCode(String.valueOf(HttpStatus.SUCCESS)); + rb.setMsg("操作成功!"); + return rb; + } + + public static ResultBean fireFail() { + ResultBean rb = new ResultBean(); + rb.setSuccess(false); + rb.setCode(String.valueOf(HttpStatus.ERROR)); + rb.setMsg("操作失败!"); + return rb; + } + + /** + * 设置返回code及msg + * + * @param codeMsg Code和Msg的枚举 + * @return + */ + public ResultBean setCode(IResultCodeMsg codeMsg) { + this.code = codeMsg.getCode(); + this.msg = codeMsg.getMsg(); + return this; + } + + /** + * 返回失败信息,并指定结果code + * + * @param codeMsg Code和Msg的枚举 + * @return + */ + public ResultBean fail(IResultCodeMsg codeMsg) { + this.setSuccess(false); + this.code = codeMsg.getCode(); + this.msg = codeMsg.getMsg(); + return this; + } + +} diff --git a/src/main/java/com/yxt/ss/gateway/api/utils/SignatureUtil.java b/src/main/java/com/yxt/ss/gateway/api/utils/SignatureUtil.java new file mode 100644 index 0000000..add06c4 --- /dev/null +++ b/src/main/java/com/yxt/ss/gateway/api/utils/SignatureUtil.java @@ -0,0 +1,75 @@ +package com.yxt.ss.gateway.api.utils; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.TreeMap; + +/** + * @description: 生成签名 + * @author: dimengzhe + * @date: 2024/11/28 + **/ +public class SignatureUtil { + + + /** + * 生成请求签名 + * + * @param parameters 请求参数 + * @param appKey 应用的 AppKey + * @param secret 密钥 + * @return 签名 + */ + public static String generateSignature(Map parameters, String appKey, String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException { + // 1. 使用 TreeMap 按照字典顺序对参数进行排序 + Map sortedParams = new TreeMap<>(parameters); + sortedParams.put("_app", appKey); // 添加应用的 AppKey + sortedParams.put("_t", String.valueOf(System.currentTimeMillis())); // 添加时间戳 + + // 2. 拼接参数字符串 + String content = joinParameters(sortedParams); + + // 3. 将密钥加在参数字符串的前后 + content = secret + content + secret; + + // 4. 计算签名 (MD5) + return md5(content); + } + + /** + * 拼接参数字符串 + * + * @param tree 排序后的参数 + * @return 拼接后的参数字符串 + */ + public static String joinParameters(Map tree) throws UnsupportedEncodingException { + StringBuilder builder = new StringBuilder(); + for (Map.Entry entry : tree.entrySet()) { + if (builder.length() > 0) { + builder.append("&"); + } + builder.append(entry.getKey()).append("="); + builder.append(URLEncoder.encode(entry.getValue(), "UTF-8")); + } + return builder.toString(); + } + + /** + * 计算 MD5 + * + * @param content 要计算 MD5 的字符串 + * @return MD5 值 + */ + public static String md5(String content) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] bytes = md.digest(content.getBytes()); + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } +} diff --git a/src/main/resources/application-devv.yml b/src/main/resources/application-devv.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/application-pro.yml b/src/main/resources/application-pro.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..fb2d262 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,8 @@ +server: + port: 9999 +spring: + application: + name: ss-gateway-api + profiles: + active: devv + diff --git a/target/classes/application-devv.yml b/target/classes/application-devv.yml new file mode 100644 index 0000000..e69de29 diff --git a/target/classes/application-pro.yml b/target/classes/application-pro.yml new file mode 100644 index 0000000..e69de29 diff --git a/target/classes/application-test.yml b/target/classes/application-test.yml new file mode 100644 index 0000000..e69de29 diff --git a/target/classes/application.yml b/target/classes/application.yml new file mode 100644 index 0000000..fb2d262 --- /dev/null +++ b/target/classes/application.yml @@ -0,0 +1,8 @@ +server: + port: 9999 +spring: + application: + name: ss-gateway-api + profiles: + active: devv +