获取用户信息接口调整
Showing
16 changed files
with
505 additions
and
15 deletions
| ... | @@ -18,7 +18,16 @@ | ... | @@ -18,7 +18,16 @@ |
| 18 | <groupId>org.springframework.boot</groupId> | 18 | <groupId>org.springframework.boot</groupId> |
| 19 | <artifactId>spring-boot-starter-web</artifactId> | 19 | <artifactId>spring-boot-starter-web</artifactId> |
| 20 | </dependency> | 20 | </dependency> |
| 21 | 21 | <dependency> | |
| 22 | <groupId>com.dtflys.forest</groupId> | ||
| 23 | <artifactId>forest-spring-boot-starter</artifactId> | ||
| 24 | <version>1.5.36</version> | ||
| 25 | </dependency> | ||
| 26 | <dependency> | ||
| 27 | <groupId>cn.hutool</groupId> | ||
| 28 | <artifactId>hutool-all</artifactId> | ||
| 29 | <version>5.8.26</version> | ||
| 30 | </dependency> | ||
| 22 | <dependency> | 31 | <dependency> |
| 23 | <groupId>org.projectlombok</groupId> | 32 | <groupId>org.projectlombok</groupId> |
| 24 | <artifactId>lombok</artifactId> | 33 | <artifactId>lombok</artifactId> | ... | ... |
| 1 | package com.topdraw.dockingapi; | 1 | package com.topdraw.dockingapi; |
| 2 | 2 | ||
| 3 | import com.dtflys.forest.springboot.annotation.ForestScan; | ||
| 3 | import lombok.extern.slf4j.Slf4j; | 4 | import lombok.extern.slf4j.Slf4j; |
| 4 | import org.springframework.boot.SpringApplication; | 5 | import org.springframework.boot.SpringApplication; |
| 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; | 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| 6 | 7 | ||
| 7 | @SpringBootApplication | 8 | @SpringBootApplication |
| 8 | @Slf4j | 9 | @Slf4j |
| 10 | @ForestScan("com.topdraw.dockingapi.http") | ||
| 9 | public class DockingApiApplication { | 11 | public class DockingApiApplication { |
| 10 | 12 | ||
| 11 | public static void main(String[] args) { | 13 | public static void main(String[] args) { | ... | ... |
| 1 | package com.topdraw.dockingapi.config; | ||
| 2 | |||
| 3 | import cn.hutool.core.bean.BeanUtil; | ||
| 4 | import cn.hutool.core.util.StrUtil; | ||
| 5 | import com.alibaba.fastjson.JSON; | ||
| 6 | import com.alibaba.fastjson.JSONObject; | ||
| 7 | import com.dtflys.forest.annotation.MethodLifeCycle; | ||
| 8 | import com.dtflys.forest.annotation.RequestAttributes; | ||
| 9 | import com.dtflys.forest.http.ForestRequest; | ||
| 10 | import com.dtflys.forest.http.ForestResponse; | ||
| 11 | import com.dtflys.forest.lifecycles.MethodAnnotationLifeCycle; | ||
| 12 | import com.dtflys.forest.reflection.ForestMethod; | ||
| 13 | import com.topdraw.dockingapi.util.DecryptUtils; | ||
| 14 | import lombok.SneakyThrows; | ||
| 15 | |||
| 16 | import java.lang.annotation.*; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * @author wenxin | ||
| 20 | * @version 1.0 | ||
| 21 | * @date 2024/5/23 下午5:45 | ||
| 22 | */ | ||
| 23 | @Documented | ||
| 24 | @MethodLifeCycle(Decode.DecodeLifeCycle.class) | ||
| 25 | @RequestAttributes | ||
| 26 | @Retention(RetentionPolicy.RUNTIME) | ||
| 27 | @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) | ||
| 28 | public @interface Decode { | ||
| 29 | |||
| 30 | String value(); | ||
| 31 | |||
| 32 | class DecodeLifeCycle implements MethodAnnotationLifeCycle<Decode, Object> { | ||
| 33 | private String key; | ||
| 34 | |||
| 35 | @Override | ||
| 36 | public void onMethodInitialized(ForestMethod method, Decode annotation) { | ||
| 37 | this.key = annotation.value(); | ||
| 38 | } | ||
| 39 | |||
| 40 | @SneakyThrows | ||
| 41 | @Override | ||
| 42 | public void onSuccess(Object data, ForestRequest request, ForestResponse response) { | ||
| 43 | String value = (String) getAttribute(request, "value"); | ||
| 44 | String content = response.getContent(); | ||
| 45 | ForestMethod<?> method = request.getMethod(); | ||
| 46 | Class<?> returnClass = method.getReturnClass(); | ||
| 47 | JSONObject responseData = JSON.parseObject(content, JSONObject.class); | ||
| 48 | if (StrUtil.isNotBlank(responseData.getString("errcode"))) { | ||
| 49 | data = BeanUtil.copyProperties(responseData, returnClass); | ||
| 50 | } else { | ||
| 51 | String encrypt = responseData.getString("encrypt"); | ||
| 52 | String bodyJson = DecryptUtils.decode(value, encrypt); | ||
| 53 | data = BeanUtil.copyProperties(JSONObject.parseObject(bodyJson), returnClass); | ||
| 54 | } | ||
| 55 | response.setResult(data); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } |
| 1 | package com.topdraw.dockingapi.config; | ||
| 2 | |||
| 3 | import com.alibaba.fastjson.JSON; | ||
| 4 | import com.dtflys.forest.annotation.MethodLifeCycle; | ||
| 5 | import com.dtflys.forest.annotation.RequestAttributes; | ||
| 6 | import com.dtflys.forest.http.ForestBody; | ||
| 7 | import com.dtflys.forest.http.ForestRequest; | ||
| 8 | import com.dtflys.forest.lifecycles.MethodAnnotationLifeCycle; | ||
| 9 | import com.dtflys.forest.reflection.ForestMethod; | ||
| 10 | import com.topdraw.dockingapi.entity.EncryptEntity; | ||
| 11 | import com.topdraw.dockingapi.util.DecryptUtils; | ||
| 12 | import lombok.SneakyThrows; | ||
| 13 | |||
| 14 | import java.lang.annotation.*; | ||
| 15 | import java.lang.reflect.Parameter; | ||
| 16 | |||
| 17 | /** | ||
| 18 | * 用Forest自定义注解实现一个自定义的签名加密注解 | ||
| 19 | * 凡用此接口修饰的方法或接口,其对应的所有请求都会执行自定义的签名加密过程 | ||
| 20 | * 而自定义的签名加密过程,由这里的@MethodLifeCycle注解指定的生命周期类进行处理 | ||
| 21 | * 可以将此注解用在接口类和方法上 | ||
| 22 | */ | ||
| 23 | @Documented | ||
| 24 | @MethodLifeCycle(Encode.EncodeLifeCycle.class) | ||
| 25 | @RequestAttributes | ||
| 26 | @Retention(RetentionPolicy.RUNTIME) | ||
| 27 | @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) | ||
| 28 | public @interface Encode { | ||
| 29 | |||
| 30 | String value() default ""; | ||
| 31 | |||
| 32 | |||
| 33 | class EncodeLifeCycle implements MethodAnnotationLifeCycle<Encode, Object> { | ||
| 34 | |||
| 35 | |||
| 36 | /** | ||
| 37 | * 当方法调用时调用此方法,此时还没有执行请求发送 | ||
| 38 | * 此方法可以获得请求对应的方法调用信息,以及动态传入的方法调用参数列表 | ||
| 39 | */ | ||
| 40 | @SneakyThrows | ||
| 41 | @Override | ||
| 42 | public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) { | ||
| 43 | String value = (String) getAttribute(request, "value"); | ||
| 44 | for (Object arg : args) { | ||
| 45 | Parameter[] parameters = method.getMethod().getParameters(); | ||
| 46 | for (int i = 0; i < parameters.length; i++) { | ||
| 47 | Encode annotation = parameters[i].getAnnotation(Encode.class); | ||
| 48 | if (annotation != null) { | ||
| 49 | Object body = args[i]; | ||
| 50 | String jsonString = JSON.toJSONString(body); | ||
| 51 | String encode = DecryptUtils.encode(value, jsonString); | ||
| 52 | EncryptEntity encodeBody = new EncryptEntity(encode); | ||
| 53 | ForestBody forestBody = request.getBody(); | ||
| 54 | //替换body | ||
| 55 | forestBody.clear(); | ||
| 56 | request.addBody(encodeBody); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | |||
| 63 | @Override | ||
| 64 | public void onMethodInitialized(ForestMethod method, Encode annotation) { | ||
| 65 | |||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | |||
| 70 | } | ||
| 71 |
| 1 | package com.topdraw.dockingapi.controller; | 1 | package com.topdraw.dockingapi.controller; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.map.MapBuilder; | ||
| 3 | import com.alibaba.fastjson.JSONArray; | 4 | import com.alibaba.fastjson.JSONArray; |
| 4 | import com.alibaba.fastjson.JSONObject; | 5 | import com.alibaba.fastjson.JSONObject; |
| 5 | import com.digital.szzz.gateway.sdk.api.GatewaySender; | 6 | import com.digital.szzz.gateway.sdk.api.GatewaySender; |
| 6 | import com.digital.szzz.gateway.sdk.bean.GatewayResponse; | 7 | import com.digital.szzz.gateway.sdk.bean.GatewayResponse; |
| 7 | import com.topdraw.dockingapi.config.EnvConfiguration; | 8 | import com.topdraw.dockingapi.config.EnvConfiguration; |
| 9 | import com.topdraw.dockingapi.entity.DecodeBody; | ||
| 10 | import com.topdraw.dockingapi.http.UserService; | ||
| 8 | import lombok.RequiredArgsConstructor; | 11 | import lombok.RequiredArgsConstructor; |
| 9 | import lombok.extern.slf4j.Slf4j; | 12 | import lombok.extern.slf4j.Slf4j; |
| 10 | import org.springframework.web.bind.annotation.*; | 13 | import org.springframework.web.bind.annotation.*; |
| ... | @@ -12,9 +15,11 @@ import org.springframework.web.bind.annotation.*; | ... | @@ -12,9 +15,11 @@ import org.springframework.web.bind.annotation.*; |
| 12 | import javax.annotation.PostConstruct; | 15 | import javax.annotation.PostConstruct; |
| 13 | import java.util.HashMap; | 16 | import java.util.HashMap; |
| 14 | import java.util.Map; | 17 | import java.util.Map; |
| 18 | import java.util.Optional; | ||
| 15 | 19 | ||
| 16 | /** | 20 | /** |
| 17 | * 对接愉快办接口 | 21 | * 对接愉快办接口 |
| 22 | * | ||
| 18 | * @author wenxin | 23 | * @author wenxin |
| 19 | * @version 1.0 | 24 | * @version 1.0 |
| 20 | * @date 2024/5/9 下午5:46 | 25 | * @date 2024/5/9 下午5:46 |
| ... | @@ -27,6 +32,8 @@ import java.util.Map; | ... | @@ -27,6 +32,8 @@ import java.util.Map; |
| 27 | public class ApiController { | 32 | public class ApiController { |
| 28 | private final EnvConfiguration configuration; | 33 | private final EnvConfiguration configuration; |
| 29 | 34 | ||
| 35 | private final UserService userService; | ||
| 36 | |||
| 30 | String url; | 37 | String url; |
| 31 | String appId; | 38 | String appId; |
| 32 | String iv; | 39 | String iv; |
| ... | @@ -46,6 +53,7 @@ public class ApiController { | ... | @@ -46,6 +53,7 @@ public class ApiController { |
| 46 | 53 | ||
| 47 | /** | 54 | /** |
| 48 | * 获取jsToken | 55 | * 获取jsToken |
| 56 | * | ||
| 49 | * @return token信息 | 57 | * @return token信息 |
| 50 | */ | 58 | */ |
| 51 | @PostMapping("/js/token") | 59 | @PostMapping("/js/token") |
| ... | @@ -55,11 +63,15 @@ public class ApiController { | ... | @@ -55,11 +63,15 @@ public class ApiController { |
| 55 | JSONObject param = new JSONObject(); | 63 | JSONObject param = new JSONObject(); |
| 56 | param.put("appId", appId); | 64 | param.put("appId", appId); |
| 57 | Map<String, String> headerMap = new HashMap<>(); | 65 | Map<String, String> headerMap = new HashMap<>(); |
| 58 | return GatewaySender.send(url, appId, method, iv, appKey, appSecretKey, param, authCode, headerMap, readTimeout, connTimeout); | 66 | return GatewaySender.send(url, appId, method, |
| 67 | iv, appKey, appSecretKey, | ||
| 68 | param, authCode, headerMap, | ||
| 69 | readTimeout, connTimeout); | ||
| 59 | } | 70 | } |
| 60 | 71 | ||
| 61 | /** | 72 | /** |
| 62 | * 获取authCode | 73 | * 获取authCode |
| 74 | * | ||
| 63 | * @param data 用户id | 75 | * @param data 用户id |
| 64 | * @return authCode信息 | 76 | * @return authCode信息 |
| 65 | */ | 77 | */ |
| ... | @@ -72,21 +84,46 @@ public class ApiController { | ... | @@ -72,21 +84,46 @@ public class ApiController { |
| 72 | param.put("userId", userId); | 84 | param.put("userId", userId); |
| 73 | param.put("forceScopes", new JSONArray().fluentAdd("ykb_user_info").fluentAdd("ykb_divide")); | 85 | param.put("forceScopes", new JSONArray().fluentAdd("ykb_user_info").fluentAdd("ykb_divide")); |
| 74 | Map<String, String> headerMap = new HashMap<>(); | 86 | Map<String, String> headerMap = new HashMap<>(); |
| 75 | return GatewaySender.send(url, appId, method, iv, appKey, appSecretKey, param, "", headerMap, readTimeout, connTimeout); | 87 | return GatewaySender.send(url, appId, method, |
| 88 | iv, appKey, appSecretKey, | ||
| 89 | param, "", headerMap, | ||
| 90 | readTimeout, connTimeout); | ||
| 76 | } | 91 | } |
| 77 | 92 | ||
| 78 | /** | 93 | /** |
| 79 | * 获取用户脱敏信息 | 94 | * 获取用户脱敏信息 |
| 95 | * | ||
| 80 | * @param data 认证code | 96 | * @param data 认证code |
| 81 | * @return 用户信息 | 97 | * @return 用户信息 |
| 82 | */ | 98 | */ |
| 83 | @PostMapping("/user/info") | 99 | @PostMapping("/user/info") |
| 84 | public GatewayResponse getUserInfoByAuthCode(@RequestBody JSONObject data) { | 100 | public DecodeBody<Object> getUserInfoByAuthCode(@RequestBody JSONObject data) { |
| 85 | String method = "app.ykb.uc.oauth.userInfo"; | 101 | //通过authCode获取用户手机号 |
| 86 | JSONObject param = new JSONObject(); | 102 | JSONObject userInfoByAuthCode = userService.getUserInfoByAuthCode(data); |
| 87 | String authCode = data.getString("authCode"); | 103 | String phone = Optional.ofNullable(userInfoByAuthCode) |
| 88 | param.put("authCode", authCode); | 104 | .map(t -> t.getJSONObject("data")) |
| 89 | Map<String, String> headerMap = new HashMap<>(); | 105 | .map(t -> t.getJSONObject("userInfo")) |
| 90 | return GatewaySender.send(url, appId, method, iv, appKey, appSecretKey, param, authCode, headerMap, readTimeout, connTimeout); | 106 | .map(t -> t.getString("phone")) |
| 107 | .orElseThrow(() -> new RuntimeException("获取用户信息失败")); | ||
| 108 | //判断手机号是否已经注册 | ||
| 109 | DecodeBody<JSONObject> register = userService.checkIsRegisterByPhoneNum(MapBuilder.<String, String>create() | ||
| 110 | .put("phone", phone).build()); | ||
| 111 | String isRegister = register.getData().getString("isRegister"); | ||
| 112 | if ("0".equals(isRegister)) { | ||
| 113 | //注册用户 | ||
| 114 | DecodeBody<Object> body = userService.privateRegister(MapBuilder.<String, String>create() | ||
| 115 | .put("phone", phone) | ||
| 116 | .put("token", "") | ||
| 117 | .build()); | ||
| 118 | String errcode = body.getErrcode(); | ||
| 119 | if (!"0".equals(errcode)) { | ||
| 120 | //注册失败直接返回失败信息 | ||
| 121 | return body; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | //获取用户信息 | ||
| 125 | return userService.privateLogin(MapBuilder.<String, String>create() | ||
| 126 | .put("phone", phone) | ||
| 127 | .put("token", "").build()); | ||
| 91 | } | 128 | } |
| 92 | } | 129 | } | ... | ... |
| 1 | package com.topdraw.dockingapi.entity; | ||
| 2 | |||
| 3 | import lombok.AllArgsConstructor; | ||
| 4 | import lombok.Data; | ||
| 5 | import lombok.NoArgsConstructor; | ||
| 6 | import lombok.experimental.Accessors; | ||
| 7 | |||
| 8 | /** | ||
| 9 | * @author wenxin | ||
| 10 | * @version 1.0 | ||
| 11 | * @date 2024/5/23 下午5:24 | ||
| 12 | */ | ||
| 13 | @Data | ||
| 14 | @NoArgsConstructor | ||
| 15 | @AllArgsConstructor | ||
| 16 | @Accessors(chain = true) | ||
| 17 | public class EncryptEntity { | ||
| 18 | |||
| 19 | private String encrypt; | ||
| 20 | |||
| 21 | } |
| 1 | package com.topdraw.dockingapi.http; | ||
| 2 | |||
| 3 | import com.alibaba.fastjson.JSONObject; | ||
| 4 | import com.dtflys.forest.annotation.BaseRequest; | ||
| 5 | import com.dtflys.forest.annotation.Body; | ||
| 6 | import com.dtflys.forest.annotation.Post; | ||
| 7 | import com.topdraw.dockingapi.config.Decode; | ||
| 8 | import com.topdraw.dockingapi.config.Encode; | ||
| 9 | import com.topdraw.dockingapi.entity.DecodeBody; | ||
| 10 | |||
| 11 | import java.util.Map; | ||
| 12 | |||
| 13 | /** | ||
| 14 | * @author wenxin | ||
| 15 | * @version 1.0 | ||
| 16 | * @date 2024/5/23 下午4:36 | ||
| 17 | */ | ||
| 18 | @BaseRequest( | ||
| 19 | baseURL = "{baseUrl}", // 默认域名 | ||
| 20 | headers = { | ||
| 21 | "Content-Type:application/json" // 默认请求头 | ||
| 22 | }, | ||
| 23 | sslProtocol = "TLS" // 默认单向SSL协议 | ||
| 24 | ) | ||
| 25 | public interface UserService { | ||
| 26 | /** | ||
| 27 | * 检查指定手机号是否注册 | ||
| 28 | * 请求体明文 | ||
| 29 | * { | ||
| 30 | * "phoneNum": "15211111111" | ||
| 31 | * } | ||
| 32 | * | ||
| 33 | * @param body 密文 key是encrypt value是加密以后的密码 | ||
| 34 | * @return isRegister(是否已注册,0:未注册;1:已注册) | ||
| 35 | */ | ||
| 36 | @Post("/cpc-ms-service-user/user/yk/checkIsRegisterByPhoneNum") | ||
| 37 | @Encode("${key}") | ||
| 38 | @Decode("${key}") | ||
| 39 | DecodeBody<JSONObject> checkIsRegisterByPhoneNum(@Body @Encode Map<String,?> body); | ||
| 40 | |||
| 41 | /** | ||
| 42 | * 用户注册 | ||
| 43 | * 请求体明文 | ||
| 44 | * { | ||
| 45 | * "phoneNum":"15211111111", | ||
| 46 | * "token":"333333333" | ||
| 47 | * } | ||
| 48 | * | ||
| 49 | * @param body 密文 key是encrypt value是加密以后的密码 | ||
| 50 | * @return errcode(错误代码,0:成功;非0:失败) | ||
| 51 | */ | ||
| 52 | @Post("/cpc-ms-service-user/user/yk/privateRegister") | ||
| 53 | @Encode("${key}") | ||
| 54 | @Decode("${key}") | ||
| 55 | DecodeBody<Object> privateRegister(@Body @Encode Map<String,?> body); | ||
| 56 | |||
| 57 | /** | ||
| 58 | * 用户登录获取用户信息 | ||
| 59 | * 请求体明文 | ||
| 60 | * { | ||
| 61 | * "phoneNum":"15211111111", | ||
| 62 | * "token":"2313123123" | ||
| 63 | * } | ||
| 64 | * | ||
| 65 | * @param body 密文 key是encrypt value是加密以后的密码 | ||
| 66 | * @return 用户信息 | ||
| 67 | */ | ||
| 68 | @Post("/cpc-ms-service-user/login/yk/privateLogin") | ||
| 69 | @Encode("${key}") | ||
| 70 | @Decode("${key}") | ||
| 71 | DecodeBody<Object> privateLogin(@Body @Encode Map<String,?> body); | ||
| 72 | |||
| 73 | |||
| 74 | /** | ||
| 75 | * 获取用户手机号码 | ||
| 76 | * | ||
| 77 | * @param body authCode | ||
| 78 | * @return 手机号 | ||
| 79 | */ | ||
| 80 | @Post("/cpc-ms-service-user/user/yk/getUserInfoByAuthCode") | ||
| 81 | JSONObject getUserInfoByAuthCode(@Body JSONObject body); | ||
| 82 | |||
| 83 | |||
| 84 | } |
| 1 | package com.topdraw.dockingapi.util; | ||
| 2 | |||
| 3 | import org.apache.commons.codec.binary.Base64; | ||
| 4 | import org.slf4j.Logger; | ||
| 5 | import org.slf4j.LoggerFactory; | ||
| 6 | |||
| 7 | import javax.crypto.Cipher; | ||
| 8 | import javax.crypto.SecretKeyFactory; | ||
| 9 | import javax.crypto.spec.DESKeySpec; | ||
| 10 | import java.security.Key; | ||
| 11 | |||
| 12 | /** | ||
| 13 | * 加解密工具 | ||
| 14 | * | ||
| 15 | * @author chenwl | ||
| 16 | * @date 2020-11-08 12:36:47 | ||
| 17 | */ | ||
| 18 | public abstract class DecryptUtils { | ||
| 19 | |||
| 20 | private static final Logger log = LoggerFactory.getLogger(DecryptUtils.class); | ||
| 21 | private static final String TRANSFORMATION_DES = "DES/ECB/PKCS5Padding"; | ||
| 22 | private static final String ALGORITHM_DES = "DES"; | ||
| 23 | |||
| 24 | /** | ||
| 25 | * DES 加密 | ||
| 26 | * | ||
| 27 | * @param key 密钥,长度不能够小于8位字节 | ||
| 28 | * @param plainText 明文 | ||
| 29 | * @return 密文 | ||
| 30 | */ | ||
| 31 | public static String encode(String key, String plainText) throws Exception { | ||
| 32 | return encode(key, plainText.getBytes()); | ||
| 33 | } | ||
| 34 | |||
| 35 | /** | ||
| 36 | * DES 加密 | ||
| 37 | * | ||
| 38 | * @param key 密钥,长度不能够小于8位字节 | ||
| 39 | * @param plainBytes 明文字节数组 | ||
| 40 | * @return 密文 | ||
| 41 | */ | ||
| 42 | public static String encode(String key, byte[] plainBytes) throws Exception { | ||
| 43 | DESKeySpec dks = new DESKeySpec(key.getBytes()); | ||
| 44 | SecretKeyFactory skf = SecretKeyFactory.getInstance(ALGORITHM_DES); | ||
| 45 | Key secretKey = skf.generateSecret(dks); | ||
| 46 | Cipher cipher = Cipher.getInstance(TRANSFORMATION_DES); | ||
| 47 | cipher.init(Cipher.ENCRYPT_MODE, secretKey); | ||
| 48 | byte[] bytes = cipher.doFinal(plainBytes); | ||
| 49 | return new String(Base64.encodeBase64(bytes)); | ||
| 50 | } | ||
| 51 | |||
| 52 | /** | ||
| 53 | * 解密 | ||
| 54 | * | ||
| 55 | * @param key 密钥,长度不能够小于8位字节 | ||
| 56 | * @param cipherText 密文 | ||
| 57 | * @return 明文 | ||
| 58 | */ | ||
| 59 | public static String decode(String key, String cipherText) throws Exception { | ||
| 60 | return decode(key, cipherText.getBytes()); | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * DES 解密 | ||
| 65 | * | ||
| 66 | * @param key 密钥,长度不能够小于8位字节 | ||
| 67 | * @param cipherBytes 密文字节数组 | ||
| 68 | * @return 明文 | ||
| 69 | */ | ||
| 70 | private static String decode(String key, byte[] cipherBytes) throws Exception { | ||
| 71 | DESKeySpec dks = new DESKeySpec(key.getBytes()); | ||
| 72 | SecretKeyFactory skf = SecretKeyFactory.getInstance(ALGORITHM_DES); | ||
| 73 | Key secretKey = skf.generateSecret(dks); | ||
| 74 | Cipher cipher = Cipher.getInstance(TRANSFORMATION_DES); | ||
| 75 | cipher.init(Cipher.DECRYPT_MODE, secretKey); | ||
| 76 | return new String(cipher.doFinal(Base64.decodeBase64(cipherBytes))); | ||
| 77 | } | ||
| 78 | |||
| 79 | |||
| 80 | } |
| ... | @@ -4,4 +4,11 @@ interface: | ... | @@ -4,4 +4,11 @@ interface: |
| 4 | appIv: kfalxHTE3Np6PbQbbZhLnA== | 4 | appIv: kfalxHTE3Np6PbQbbZhLnA== |
| 5 | appKey: Rd+oZa5bYfhiNK9O0dc0ng== | 5 | appKey: Rd+oZa5bYfhiNK9O0dc0ng== |
| 6 | appSecret: x6en8WE3 | 6 | appSecret: x6en8WE3 |
| 7 | url: http://23.210.52.243:44207/gateway/open/api/do | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 7 | url: http://23.210.52.243:44207/gateway/open/api/do | ||
| 8 | |||
| 9 | forest: | ||
| 10 | variables: | ||
| 11 | baseUrl: https://cpcapi.cbg.cn/ | ||
| 12 | key: wmsj2021 | ||
| 13 | server: | ||
| 14 | port: 7078 | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -4,4 +4,10 @@ interface: | ... | @@ -4,4 +4,10 @@ interface: |
| 4 | appIv: ynDi62eQ8WKQtZhUMUqTmQ== | 4 | appIv: ynDi62eQ8WKQtZhUMUqTmQ== |
| 5 | appKey: y4pBvyDY8cgSNsxukn0DlQ== | 5 | appKey: y4pBvyDY8cgSNsxukn0DlQ== |
| 6 | appSecret: 04t5li0m | 6 | appSecret: 04t5li0m |
| 7 | url: https://ykbapp-test.cqdcg.com:1443/gateway/open/api/do | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 7 | url: https://ykbapp-test.cqdcg.com:1443/gateway/open/api/do | ||
| 8 | forest: | ||
| 9 | variables: | ||
| 10 | baseUrl: https://cpcapi.cbg.cn/ | ||
| 11 | key: wmsj2021 | ||
| 12 | server: | ||
| 13 | port: 7077 | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
src/main/resources/bootstrap.yml
0 → 100644
| 1 | forest: | ||
| 2 | backend: okhttp3 # 后端HTTP框架(默认为 okhttp3) | ||
| 3 | max-connections: 1000 # 连接池最大连接数(默认为 500) | ||
| 4 | max-route-connections: 500 # 每个路由的最大连接数(默认为 500) | ||
| 5 | max-request-queue-size: 100 # [自v1.5.22版本起可用] 最大请求等待队列大小 | ||
| 6 | max-async-thread-size: 300 # [自v1.5.21版本起可用] 最大异步线程数 | ||
| 7 | max-async-queue-size: 16 # [自v1.5.22版本起可用] 最大异步线程池队列大小 | ||
| 8 | timeout: 3000 # [已不推荐使用] 请求超时时间,单位为毫秒(默认为 3000) | ||
| 9 | connect-timeout: 3000 # 连接超时时间,单位为毫秒(默认为 timeout) | ||
| 10 | read-timeout: 3000 # 数据读取超时时间,单位为毫秒(默认为 timeout) | ||
| 11 | max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试) | ||
| 12 | ssl-protocol: TLS # 单向验证的HTTPS的默认TLS协议(默认为 TLS) | ||
| 13 | log-enabled: true # 打开或关闭日志(默认为 true) | ||
| 14 | log-request: true # 打开/关闭Forest请求日志(默认为 true) | ||
| 15 | log-response-status: true # 打开/关闭Forest响应状态日志(默认为 true) | ||
| 16 | log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false) | ||
| 17 | async-mode: platform # [自v1.5.27版本起可用] 异步模式(默认为 platform) | ||
| 18 | variables: | ||
| 19 | userInfoUrl: https://cpcapi.cbg.cn | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | package com.topdraw.dockingapi; | ||
| 2 | |||
| 3 | import com.topdraw.dockingapi.util.DecryptUtils; | ||
| 4 | import lombok.SneakyThrows; | ||
| 5 | import org.bouncycastle.jce.provider.BouncyCastleProvider; | ||
| 6 | import org.junit.jupiter.api.Test; | ||
| 7 | |||
| 8 | import javax.crypto.Cipher; | ||
| 9 | import javax.crypto.spec.SecretKeySpec; | ||
| 10 | import java.nio.charset.StandardCharsets; | ||
| 11 | import java.security.Security; | ||
| 12 | |||
| 13 | /** | ||
| 14 | * @author wenxin | ||
| 15 | * @version 1.0 | ||
| 16 | * @date 2024/5/23 下午4:40 | ||
| 17 | */ | ||
| 18 | public class ApiTest { | ||
| 19 | |||
| 20 | |||
| 21 | @Test | ||
| 22 | public void testMain() throws Exception { | ||
| 23 | // 添加BouncyCastle提供者 | ||
| 24 | Security.addProvider(new BouncyCastleProvider()); | ||
| 25 | // 密钥 | ||
| 26 | byte[] keyBytes = "wmsj2021".getBytes(StandardCharsets.UTF_8); // DES密钥长度为8字节 | ||
| 27 | // 需要加密的数据 | ||
| 28 | String text = "{\"phoneNum\":\"15983678047\"}"; | ||
| 29 | byte[] data = text.getBytes(StandardCharsets.UTF_8); | ||
| 30 | // 创建密钥 | ||
| 31 | SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "DES"); | ||
| 32 | // 创建Cipher实例 | ||
| 33 | Cipher cipher = Cipher.getInstance("DES/ECB/PKCS7Padding", "BC"); | ||
| 34 | // 初始化Cipher | ||
| 35 | cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); | ||
| 36 | // 执行加密 | ||
| 37 | byte[] encryptedData = cipher.doFinal(data); | ||
| 38 | // 打印加密结果(通常加密后的数据进行Base64编码或者十六进制编码显示) | ||
| 39 | System.out.println("Encrypted Data: " + bytesToHex(encryptedData)); | ||
| 40 | } | ||
| 41 | |||
| 42 | // 将字节转换为十六进制字符串 | ||
| 43 | public static String bytesToHex(byte[] bytes) { | ||
| 44 | StringBuilder hexString = new StringBuilder(); | ||
| 45 | for (byte b : bytes) { | ||
| 46 | String hex = Integer.toHexString(0xff & b); | ||
| 47 | if (hex.length() == 1) hexString.append('0'); | ||
| 48 | hexString.append(hex); | ||
| 49 | } | ||
| 50 | return hexString.toString(); | ||
| 51 | } | ||
| 52 | |||
| 53 | @SneakyThrows | ||
| 54 | @Test | ||
| 55 | public void testEncode(){ | ||
| 56 | String text = "{\"phoneNum\":\"15983678047\"}"; | ||
| 57 | System.out.println(DecryptUtils.encode("wmsj2021", text)); | ||
| 58 | String tt="U0ELEkckqqxwzutWXbySgJmGbWQovd9n7UZSWqYt5HpXOxOsQwTnrjGp7geAhD/Mp9Jy3okXkRtt0cuFDdlMjPDgsBK3SMu0"; | ||
| 59 | System.out.println(DecryptUtils.decode("wmsj2021", tt)); | ||
| 60 | } | ||
| 61 | } |
| 1 | package com.topdraw.dockingapi; | 1 | package com.topdraw.dockingapi; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONObject; | ||
| 4 | import com.topdraw.dockingapi.http.UserService; | ||
| 3 | import org.junit.jupiter.api.Test; | 5 | import org.junit.jupiter.api.Test; |
| 4 | import org.springframework.boot.test.context.SpringBootTest; | 6 | import org.springframework.boot.test.context.SpringBootTest; |
| 5 | 7 | ||
| 8 | import javax.annotation.Resource; | ||
| 9 | |||
| 6 | @SpringBootTest | 10 | @SpringBootTest |
| 7 | class DockingApiApplicationTests { | 11 | class DockingApiApplicationTests { |
| 8 | 12 | ||
| 13 | @Resource | ||
| 14 | private UserService userService; | ||
| 15 | |||
| 9 | @Test | 16 | @Test |
| 10 | void contextLoads() { | 17 | void contextLoads() { |
| 18 | JSONObject param = new JSONObject(); | ||
| 19 | param.put("phoneNum","15636524584"); | ||
| 20 | System.out.println(userService.checkIsRegisterByPhoneNum(param)); | ||
| 11 | } | 21 | } |
| 12 | 22 | ||
| 13 | } | 23 | } | ... | ... |
-
Please register or sign in to post a comment