
commit
ef2e5597b3
15 changed files with 528 additions and 0 deletions
@ -0,0 +1,72 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
|
|||
<parent> |
|||
<groupId>com.yxt</groupId> |
|||
<artifactId>yxt-parent</artifactId> |
|||
<version>0.0.1</version> |
|||
<relativePath/> |
|||
</parent> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
|
|||
<artifactId>ss-gateway-api</artifactId> |
|||
<groupId>ss-gateway-api</groupId> |
|||
<version>0.0.1</version> |
|||
|
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.springframework.cloud</groupId> |
|||
<artifactId>spring-cloud-starter-gateway</artifactId> |
|||
</dependency> |
|||
<!-- <dependency> |
|||
<groupId>com.alibaba.cloud</groupId> |
|||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> |
|||
</dependency>--> |
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<version>1.18.24</version> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework</groupId> |
|||
<artifactId>spring-webmvc</artifactId> |
|||
</dependency> |
|||
|
|||
</dependencies> |
|||
|
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
<version>2.5.6</version> |
|||
<executions> |
|||
<execution> |
|||
<goals> |
|||
<goal>repackage</goal> |
|||
</goals> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
</plugins> |
|||
<resources> |
|||
<resource> |
|||
<directory>src/main/java</directory> |
|||
<includes> |
|||
<include>**/*Mapper.xml</include> |
|||
</includes> |
|||
</resource> |
|||
<resource> |
|||
<directory>src/main/resources</directory> |
|||
<includes> |
|||
<include>**/*.*</include> |
|||
</includes> |
|||
<filtering>false</filtering> |
|||
</resource> |
|||
</resources> |
|||
</build> |
|||
|
|||
</project> |
@ -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); |
|||
} |
|||
} |
@ -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<String> getSign(@RequestParam("parameters") Map<String, String> parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException { |
|||
ResultBean<String> rb = ResultBean.fireFail(); |
|||
String sign = SignatureUtil.generateSignature(parameters, appKey, secret); |
|||
return rb.success().setData(sign); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 对传入的参数集合进行签名处理 |
|||
* 返回系统参数 |
|||
*/ |
|||
@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 { |
|||
ResultBean<Map<String, String>> rb = ResultBean.fireFail(); |
|||
// 1. 使用 TreeMap 按照字典顺序对参数进行排序
|
|||
Map<String, String> 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<Boolean> validateSignature(@RequestParam("parameters") Map<String, String> parameters, @RequestParam("appKey") String appKey, @RequestParam("secret") String secret, @RequestParam("receivedSignature") String receivedSignature) throws UnsupportedEncodingException, NoSuchAlgorithmException { |
|||
ResultBean<Boolean> rb = ResultBean.fireFail(); |
|||
// 1. 重新生成签名
|
|||
String calculatedSignature = SignatureUtil.generateSignature(parameters, appKey, secret); |
|||
|
|||
// 2. 比较计算出来的签名和请求中的签名
|
|||
boolean validd = calculatedSignature.equals(receivedSignature); |
|||
return rb.success().setData(validd); |
|||
} |
|||
|
|||
|
|||
} |
@ -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"; |
|||
|
|||
} |
@ -0,0 +1,44 @@ |
|||
/********************************************************* |
|||
********************************************************* |
|||
******************** ******************* |
|||
************* ************ |
|||
******* _oo0oo_ ******* |
|||
*** o8888888o *** |
|||
* 88" . "88 * |
|||
* (| -_- |) * |
|||
* 0\ = /0 * |
|||
* ___/`---'\___ * |
|||
* .' \\| |// '. *
|
|||
* / \\||| : |||// \ *
|
|||
* / _||||| -:- |||||- \ * |
|||
* | | \\\ - /// | | *
|
|||
* | \_| ''\---/'' |_/ | * |
|||
* \ .-\__ '-' ___/-. / * |
|||
* ___'. .' /--.--\ `. .'___ * |
|||
* ."" '< `.___\_<|>_/___.' >' "". * |
|||
* | | : `- \`.;`\ _ /`;.`/ - ` : | | * |
|||
* \ \ `_. \_ __\ /__ _/ .-` / / * |
|||
* =====`-.____`.___ \_____/___.-`___.-'===== * |
|||
* `=---=' * |
|||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * |
|||
*********__佛祖保佑__永无BUG__验收通过__钞票多多__********* |
|||
*********************************************************/ |
|||
package com.yxt.ss.gateway.api.utils; |
|||
|
|||
/** |
|||
* Project: yxt-common <br/> |
|||
* File: IResultCodeMsg.java <br/> |
|||
* Class: com.yxt.common.core.result.IResultCodeMsg <br/> |
|||
* Description: <描述类的功能>. <br/> |
|||
* Copyright: Copyright (c) 2011 <br/> |
|||
* Company: https://gitee.com/liuzp315 <br/>
|
|||
* Makedate: 2021/9/11 下午11:00 <br/> |
|||
* |
|||
* @author popo |
|||
* @version 1.0 |
|||
* @since 1.0 |
|||
*/ |
|||
public interface IResultCodeMsg { |
|||
String getCode(); |
|||
String getMsg(); |
|||
} |
@ -0,0 +1,191 @@ |
|||
package com.yxt.ss.gateway.api.utils; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* Project: yxt-common-core <br/> |
|||
* File: ResultBean.java <br/> |
|||
* Class: com.yxt.common.core.result.ResultBean <br/> |
|||
* Description: 通过接口、Rest、逻辑处理执行后的结果信息. <br/> |
|||
* Copyright: Copyright (c) 2011 <br/> |
|||
* Company: https://gitee.com/liuzp315 <br/>
|
|||
* Makedate: 2020/8/4 0:51 <br/> |
|||
* |
|||
* @author liupopo |
|||
* @version 1.0 |
|||
* @since 1.0 |
|||
*/ |
|||
public class ResultBean<T> 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<T> 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<T> setSuccess(boolean success) { |
|||
this.success = success; |
|||
return this; |
|||
} |
|||
|
|||
public String getMsg() { |
|||
return msg; |
|||
} |
|||
|
|||
public ResultBean<T> setMsg(String msg) { |
|||
this.msg = msg; |
|||
return this; |
|||
} |
|||
|
|||
public String getCode() { |
|||
return code; |
|||
} |
|||
|
|||
public ResultBean<T> setCode(String code) { |
|||
this.code = code; |
|||
return this; |
|||
} |
|||
|
|||
public T getData() { |
|||
return data; |
|||
} |
|||
|
|||
public ResultBean<T> setData(T data) { |
|||
this.data = data; |
|||
return this; |
|||
} |
|||
|
|||
public ResultBean<T> successOne() { |
|||
this.setSuccess(true); |
|||
this.setCode("0"); |
|||
this.setMessage("成功!"); |
|||
return this; |
|||
} |
|||
|
|||
public ResultBean<T> failOne() { |
|||
this.setSuccess(false); |
|||
this.setCode(String.valueOf(HttpStatus.ERROR)); |
|||
this.setMessage("操作失败!"); |
|||
return this; |
|||
} |
|||
|
|||
public ResultBean<T> success() { |
|||
this.setSuccess(true); |
|||
this.setCode(String.valueOf(HttpStatus.SUCCESS)); |
|||
this.setMsg("操作成功!"); |
|||
return this; |
|||
} |
|||
|
|||
public ResultBean<T> fail() { |
|||
this.setSuccess(false); |
|||
this.setCode(String.valueOf(HttpStatus.ERROR)); |
|||
this.setMsg("操作失败!"); |
|||
return this; |
|||
} |
|||
|
|||
public static <T> ResultBean<T> fireSuccess() { |
|||
ResultBean<T> rb = new ResultBean<T>(); |
|||
rb.setSuccess(true); |
|||
rb.setCode(String.valueOf(HttpStatus.SUCCESS)); |
|||
rb.setMsg("操作成功!"); |
|||
return rb; |
|||
} |
|||
|
|||
public static <T> ResultBean<T> fireFail() { |
|||
ResultBean<T> rb = new ResultBean<T>(); |
|||
rb.setSuccess(false); |
|||
rb.setCode(String.valueOf(HttpStatus.ERROR)); |
|||
rb.setMsg("操作失败!"); |
|||
return rb; |
|||
} |
|||
|
|||
/** |
|||
* 设置返回code及msg |
|||
* |
|||
* @param codeMsg Code和Msg的枚举 |
|||
* @return |
|||
*/ |
|||
public ResultBean<T> setCode(IResultCodeMsg codeMsg) { |
|||
this.code = codeMsg.getCode(); |
|||
this.msg = codeMsg.getMsg(); |
|||
return this; |
|||
} |
|||
|
|||
/** |
|||
* 返回失败信息,并指定结果code |
|||
* |
|||
* @param codeMsg Code和Msg的枚举 |
|||
* @return |
|||
*/ |
|||
public ResultBean<T> fail(IResultCodeMsg codeMsg) { |
|||
this.setSuccess(false); |
|||
this.code = codeMsg.getCode(); |
|||
this.msg = codeMsg.getMsg(); |
|||
return this; |
|||
} |
|||
|
|||
} |
@ -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<String, String> parameters, String appKey, String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException { |
|||
// 1. 使用 TreeMap 按照字典顺序对参数进行排序
|
|||
Map<String, String> 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<String, String> tree) throws UnsupportedEncodingException { |
|||
StringBuilder builder = new StringBuilder(); |
|||
for (Map.Entry<String, String> 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(); |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
server: |
|||
port: 9999 |
|||
spring: |
|||
application: |
|||
name: ss-gateway-api |
|||
profiles: |
|||
active: devv |
|||
|
@ -0,0 +1,8 @@ |
|||
server: |
|||
port: 9999 |
|||
spring: |
|||
application: |
|||
name: ss-gateway-api |
|||
profiles: |
|||
active: devv |
|||
|
Loading…
Reference in new issue