This commit is contained in:
wxp01309236
2023-06-19 19:28:54 +08:00
parent dd7b77e3ae
commit 0ec142170e
10 changed files with 300 additions and 28 deletions

View File

@@ -120,4 +120,6 @@ public class CommonConstants {
public static final String TRANSFER = "transfer"; public static final String TRANSFER = "transfer";
public static final String FIX_MOBILE_OPENID_TEST = "HSAY5531DA7";
public static final String FIX_MOBILE_OPENID_ONLINE = "HSAY4AF322E";
} }

View File

@@ -0,0 +1,139 @@
package com.cool.store.utils;
import com.cool.store.exception.ServiceException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* https://cloud.tencent.com/developer/article/1823249
* 前后端约定
*/
public class AESDecryptor {
private static String Algorithm = "AES";
private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; //算法/模式/补码方式
public static byte[] generatorKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(Algorithm);
keyGenerator.init(256);//默认128获得无政策权限后可为192或256
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
}
public static IvParameterSpec getIv(byte[] ivstr) throws UnsupportedEncodingException {
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivstr);
return ivParameterSpec;
}
public static String encrypt(String src, String keystr, IvParameterSpec iv) throws
NoSuchAlgorithmException,
NoSuchPaddingException,
InvalidKeyException,
IllegalBlockSizeException,
BadPaddingException,
UnsupportedEncodingException,
InvalidAlgorithmParameterException {
byte[] key = keystr.getBytes("utf-8");
SecretKey secretKey = new SecretKeySpec(key, Algorithm);
IvParameterSpec ivParameterSpec = iv;
Cipher cipher = Cipher.getInstance(AlgorithmProvider);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));
return byteToHexString(cipherBytes);
}
public static String decrypt(String src, String keystr) {
try {
byte[] key = keystr.getBytes("utf-8");
SecretKey secretKey = new SecretKeySpec(key, Algorithm);
IvParameterSpec ivParameterSpec = getIv(Arrays.copyOfRange(keystr.getBytes("utf-8"), 0, 16));
Cipher cipher = Cipher.getInstance(AlgorithmProvider);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] hexBytes = hexStringToBytes(src);
byte[] plainBytes = cipher.doFinal(hexBytes);
return new String(plainBytes, "utf-8");
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
/**
* 将byte转换为16进制字符串
*
* @param src
* @return
*/
public static String byteToHexString(byte[] src) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xff;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
sb.append("0");
}
sb.append(hv);
}
return sb.toString();
}
/**
* 将16进制字符串装换为byte数组
*
* @param hexString
* @return
*/
public static byte[] hexStringToBytes(String hexString) {
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] b = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return b;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
public static void main(String[] args) {
try {
/* // 密钥必须是16的倍数
String keystr = "0123456789ABCDEF";
String ivstr = "0123456789101112";
String src = "Hello World";
System.out.println("密钥:" + keystr);
System.out.println("偏移量:" + ivstr);
System.out.println("原字符串:" + src);
IvParameterSpec iv = getIv(ivstr);
String enc = encrypt(src, keystr, iv);
System.out.println("加密:" + enc);
*/
String enc = "38395651e391c4b8ca327c4742b7f52f";
String keystr = "77fea013c3a6459685b83c21a2fc3411";
String ivstr = "77fea013c3a64596";
// IvParameterSpec iv = getIv(ivstr);
String dec = decrypt(enc, keystr);
System.out.println("解密:" + dec);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -213,8 +213,8 @@
<if test="mobile != null and mobile!=''"> <if test="mobile != null and mobile!=''">
mobile = #{mobile}, mobile = #{mobile},
</if> </if>
where partner_id = #{partnerId}
</set> </set>
where partner_id = #{partnerId}
</update> </update>
<select id="getByPartnerIdAndLineId" resultMap="BaseResultMap" > <select id="getByPartnerIdAndLineId" resultMap="BaseResultMap" >

View File

@@ -14,7 +14,7 @@ public interface WechatMiniAppService {
PartnerUserInfoVO miniProgramLogin(MiniProgramLoginDTO param); PartnerUserInfoVO miniProgramLogin(MiniProgramLoginDTO param);
Boolean updateUserPhoneNumber(MobileUpdateRequest request, PartnerUserInfoVO userInfoVO); String updateUserPhoneNumber(MobileUpdateRequest request, PartnerUserInfoVO userInfoVO);
PartnerUserInfoVO getUserInfo(String mobile, String openId); PartnerUserInfoVO getUserInfo(String mobile, String openId);
} }

View File

@@ -120,7 +120,8 @@ public class WechatMiniAppServiceImpl implements WechatMiniAppService {
} }
@Override @Override
public Boolean updateUserPhoneNumber(MobileUpdateRequest request, PartnerUserInfoVO userInfoVO) { public String updateUserPhoneNumber(MobileUpdateRequest request, PartnerUserInfoVO userInfoVO) {
String newMobile = "";
HyPartnerUserInfoDO oldUserInfo = hyPartnerUserInfoDAO.selectByMobile(userInfoVO.getMobile()); HyPartnerUserInfoDO oldUserInfo = hyPartnerUserInfoDAO.selectByMobile(userInfoVO.getMobile());
if (oldUserInfo == null) { if (oldUserInfo == null) {
throw new ServiceException(ErrorCodeEnum.PARTNER_USER_NOT_EXIST); throw new ServiceException(ErrorCodeEnum.PARTNER_USER_NOT_EXIST);
@@ -130,19 +131,26 @@ public class WechatMiniAppServiceImpl implements WechatMiniAppService {
// 获取手机号码 // 获取手机号码
PhoneInfoDTO phoneInfoDTO = wechatRest.getUserPhoneNumber(request.getMobileCode(), accessToken); PhoneInfoDTO phoneInfoDTO = wechatRest.getUserPhoneNumber(request.getMobileCode(), accessToken);
if(phoneInfoDTO != null && phoneInfoDTO.getPhoneInfo() != null && StringUtils.isNotBlank(phoneInfoDTO.getPhoneInfo().getPhoneNumber())){ if(phoneInfoDTO != null && phoneInfoDTO.getPhoneInfo() != null && StringUtils.isNotBlank(phoneInfoDTO.getPhoneInfo().getPhoneNumber())){
HyPartnerUserInfoDO newUserInfo = hyPartnerUserInfoDAO.selectByMobile(phoneInfoDTO.getPhoneInfo().getPhoneNumber()); newMobile = phoneInfoDTO.getPhoneInfo().getPhoneNumber();
HyPartnerUserInfoDO newUserInfo = hyPartnerUserInfoDAO.selectByMobile(newMobile);
if (newUserInfo != null) { if (newUserInfo != null) {
throw new ServiceException(ErrorCodeEnum.NEW_MOBILE_HAS_EXIST); throw new ServiceException(ErrorCodeEnum.NEW_MOBILE_HAS_EXIST);
} }
oldUserInfo.setMobile(phoneInfoDTO.getPhoneInfo().getPhoneNumber()); oldUserInfo.setMobile(newMobile);
hyPartnerUserInfoDAO.updateByPrimaryKeySelective(oldUserInfo); hyPartnerUserInfoDAO.updateByPrimaryKeySelective(oldUserInfo);
} }
return true; return newMobile;
} }
@Override @Override
public PartnerUserInfoVO getUserInfo(String mobile, String openId) { public PartnerUserInfoVO getUserInfo(String mobile, String openId) {
PartnerUserInfoVO userInfoVO = new PartnerUserInfoVO(); PartnerUserInfoVO userInfoVO = new PartnerUserInfoVO();
if(CommonConstants.FIX_MOBILE_OPENID_TEST.equals(mobile) || CommonConstants.FIX_MOBILE_OPENID_ONLINE.equals(mobile) ){
userInfoVO.setMobile(mobile);
userInfoVO.setOpenid(mobile);
userInfoVO.setPartnerId("");
return userInfoVO;
}
HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByMobile(mobile); HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByMobile(mobile);
BeanUtil.copyProperties(hyPartnerUserInfoDO, userInfoVO); BeanUtil.copyProperties(hyPartnerUserInfoDO, userInfoVO);
HyPartnerUserPlatformBindDO hyPartnerUserPlatformBindDO = hyPartnerUserPlatformBindDAO.getByPartnerId(hyPartnerUserInfoDO.getPartnerId()); HyPartnerUserPlatformBindDO hyPartnerUserPlatformBindDO = hyPartnerUserPlatformBindDAO.getByPartnerId(hyPartnerUserInfoDO.getPartnerId());

View File

@@ -0,0 +1,26 @@
package com.cool.store.config;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Author: JCccc
* @Date: 2022-6-12 10:35
* @Description:
*/
public class BodyWrapperFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(servletRequest instanceof HttpServletRequest) {
requestWrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest);
}
if(requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
}

View File

@@ -0,0 +1,60 @@
package com.cool.store.config;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* @Author: JCccc
* @Date: 2022-6-12 10:36
* @Description: 重写一个自己的 RequestWrapper 拿出body给自己用
*/
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
try (StringWriter writer = new StringWriter()) {
int read;
char[] buf = new char[1024 * 8];
while ((read = reader.read(buf)) != -1) {
writer.write(buf, 0, read);
}
this.body = writer.getBuffer().toString().getBytes();
}
}
public String getBody(){
return new String(body, StandardCharsets.UTF_8);
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}

View File

@@ -7,10 +7,7 @@ import com.cool.store.context.PartnerUserHolder;
import com.cool.store.enums.ErrorCodeEnum; import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.response.ResponseResult; import com.cool.store.response.ResponseResult;
import com.cool.store.service.WechatMiniAppService; import com.cool.store.service.WechatMiniAppService;
import com.cool.store.utils.AesUtil; import com.cool.store.utils.*;
import com.cool.store.utils.Md5Utils;
import com.cool.store.utils.Sha1Utils;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.PartnerUserInfoVO; import com.cool.store.vo.PartnerUserInfoVO;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -26,8 +23,10 @@ import javax.servlet.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
/** /**
* @author ydw * @author ydw
@@ -81,41 +80,51 @@ public class SignValidateFilter implements Filter {
MDC.put(CommonConstants.REQUEST_ID, UUIDUtils.get32UUID()); MDC.put(CommonConstants.REQUEST_ID, UUIDUtils.get32UUID());
HttpServletResponse response = (HttpServletResponse) servletResponse; HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletRequest request = (HttpServletRequest) servletRequest;
CustomHttpServletRequestWrapper wrapper = (CustomHttpServletRequestWrapper) request;
String uri = request.getRequestURI(); String uri = request.getRequestURI();
String method = request.getMethod(); String method = request.getMethod();
String userStr = ""; String userStr = "";
boolean isInWhiteList = excludePath(uri); boolean isInWhiteList = excludePath(uri);
log.info("url:{}", uri); log.info("url:{}", uri);
/* if ( !isInWhiteList && !method.equals("OPTIONS")) { if ( !isInWhiteList && !method.equals("OPTIONS")) {
Map<String, String[]> parameterMap = request.getParameterMap(); String params = "";
String jsonStr = JSONObject.toJSONString(parameterMap); if("GET".equalsIgnoreCase(method)){
JSONObject obj = JSONObject.parseObject(jsonStr); Map<String, String> parameterMap = new HashMap();
log.info("params:{}", obj.toJSONString()); Map<String, String[]> requestMap = request.getParameterMap();
String params = obj.toJSONString(); for(String key : requestMap.keySet()){
parameterMap.put(key, requestMap.get(key)[0]);
}
params = JSONObject.toJSONString(parameterMap);
}else if("POST".equalsIgnoreCase(method)){
params = wrapper.getBody();
// params = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
}
log.info("params:{}", params);
String sign = request.getHeader("SIGN"); String sign = request.getHeader("SIGN");
String nonce = request.getHeader("NONCE"); String nonce = request.getHeader("NONCE");
String timestamp = request.getHeader("TIMESTAMP"); String timestamp = request.getHeader("TIMESTAMP");
String aesPhone = request.getHeader("PHONE"); String aesPhone = request.getHeader("PHONE");
String openid = request.getHeader("OPENID"); String openid = request.getHeader("OPENID");
String phone = AesUtil.decrypt(aesPhone, signKey); String phone = AESDecryptor.decrypt(aesPhone, signKey);
String md5Value = phone + Md5Utils.md5(Md5Utils.md5(openid)); String plaintextOpenid = AESDecryptor.decrypt(openid, signKey);
log.info("sign:{}, nonce:{}, timestamp:{},aesPhone:{}, openid:{}, 解密后的手机号:{}, md5Value:{}", String md5Value = phone + Md5Utils.md5(Md5Utils.md5(plaintextOpenid));
sign, nonce, timestamp, aesPhone, openid, phone, md5Value); log.info("sign:{}, nonce:{}, timestamp:{},aesPhone:{}, openid:{}, 解密后的手机号:{}, md5Value:{}, 明文plaintextOpenid:{}",
sign, nonce, timestamp, aesPhone, openid, phone, md5Value, plaintextOpenid);
String signStr = timestamp + nonce + params + signKey + md5Value; String signStr = timestamp + nonce + params + signKey + md5Value;
String newSign = Sha1Utils.getSha1(signStr.getBytes()); String newSign = Sha1Utils.getSha1(signStr.getBytes());
log.info("newSign: {}", newSign); log.info("signStr: {}, newSign: {}", signStr, newSign);
// 前后端验签不等 // 前后端验签不等
if (!newSign.equals(sign)) { if (!newSign.equals(sign)) {
response.setStatus(HttpStatus.OK.value()); response.setStatus(HttpStatus.OK.value());
response.getWriter().write(JSON.toJSONString(ResponseResult.fail(ErrorCodeEnum.SIGN_FAIL))); response.getWriter().write(JSON.toJSONString(ResponseResult.fail(ErrorCodeEnum.SIGN_FAIL)));
return; return;
} }
PartnerUserInfoVO partnerUserInfoVO = wechatMiniAppService.getUserInfo(phone, openid); PartnerUserInfoVO partnerUserInfoVO = wechatMiniAppService.getUserInfo(phone, plaintextOpenid);
if(partnerUserInfoVO != null){ if(partnerUserInfoVO != null){
userStr = JSONObject.toJSONString(partnerUserInfoVO); userStr = JSONObject.toJSONString(partnerUserInfoVO);
log.info("url:{}, userStr:{}", uri, userStr); log.info("url:{}, userStr:{}", uri, userStr);
} }
}*/ }
try { try {
PartnerUserHolder.setUser(userStr); PartnerUserHolder.setUser(userStr);
filterChain.doFilter(servletRequest, servletResponse); filterChain.doFilter(servletRequest, servletResponse);

View File

@@ -0,0 +1,29 @@
package com.cool.store.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: JCccc
* @Date: 2022-6-23 10:52
* @Description:
*/
@Configuration
public class WebApplicationConfig {
@Bean
BodyWrapperFilter getBodyWrapperFilter(){
return new BodyWrapperFilter();
}
@Bean("bodyWrapperFilter")
public FilterRegistrationBean<BodyWrapperFilter> checkUserFilter(BodyWrapperFilter bodyWrapperFilter) {
FilterRegistrationBean<BodyWrapperFilter> registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(bodyWrapperFilter);
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(1);
registrationBean.setAsyncSupported(true);
return registrationBean;
}
}

View File

@@ -38,16 +38,15 @@ public class MiniProgramAppController {
@ApiOperation("更新手机号") @ApiOperation("更新手机号")
@PostMapping("/updateUserPhoneNumber") @PostMapping("/updateUserPhoneNumber")
public ResponseResult<Boolean> updateUserPhoneNumber(@RequestBody @Valid MobileUpdateRequest request) { public ResponseResult<String> updateUserPhoneNumber(@RequestBody @Valid MobileUpdateRequest request) {
PartnerUserInfoVO userInfoVO = PartnerUserHolder.getUser(); PartnerUserInfoVO userInfoVO = PartnerUserHolder.getUser();
return ResponseResult.success(wechatMiniAppService.updateUserPhoneNumber(request, userInfoVO)); return ResponseResult.success(wechatMiniAppService.updateUserPhoneNumber(request, userInfoVO));
} }
@ApiOperation("根据mobile和openId获取用户信息") @ApiOperation("根据mobile和openId获取用户信息")
@PostMapping("/getUserInfo") @GetMapping("/getUserInfo")
public ResponseResult<PartnerUserInfoVO> getUserInfo(@RequestParam(value = "mobile",required = false) String mobile, public ResponseResult<PartnerUserInfoVO> getUserInfo(){
@RequestParam(value = "openId",required = false) String openId){ PartnerUserInfoVO userInfoVO = PartnerUserHolder.getUser();
PartnerUserInfoVO userInfoVO = wechatMiniAppService.getUserInfo(mobile, openId);
return ResponseResult.success(userInfoVO); return ResponseResult.success(userInfoVO);
} }
} }