diff --git a/hai-service/src/main/java/com/hai/common/utils/WxUtils.java b/hai-service/src/main/java/com/hai/common/utils/WxUtils.java index 874dcae7..95a02611 100644 --- a/hai-service/src/main/java/com/hai/common/utils/WxUtils.java +++ b/hai-service/src/main/java/com/hai/common/utils/WxUtils.java @@ -540,4 +540,48 @@ public class WxUtils { } } + /** + * 用SHA1算法生成安全签名 + * @param data 数据 + * @return 安全签名 + * @throws Exception + */ + public static String getSHA1(final Map data) throws Exception + { + try { + Set keySet = data.keySet(); + String[] keyArray = keySet.toArray(new String[keySet.size()]); + Arrays.sort(keyArray); + StringBuilder sb = new StringBuilder(); + for (String k : keyArray) { + if (k.equals(WXPayConstants.FIELD_SIGN) || k.equals("apiKey")) { + continue; + } + if (data.get(k) != null) // 参数值为空,则不参与签名 + { + sb.append(k).append("=").append(data.get(k)).append("&"); + } + } + String str = sb.substring(0 , sb.length()-1); + // SHA1签名生成 + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(str.getBytes()); + byte[] digest = md.digest(); + + StringBuffer hexstr = new StringBuffer(); + String shaHex = ""; + for (int i = 0; i < digest.length; i++) { + shaHex = Integer.toHexString(digest[i] & 0xFF); + if (shaHex.length() < 2) { + hexstr.append(0); + } + hexstr.append(shaHex); + } + return hexstr.toString(); + } catch (Exception e) { + e.printStackTrace(); + throw new Exception(String.format("Invalid sign_type: %s")); + } + } + } diff --git a/v1/src/main/java/com/v1/config/SysConfig.java b/v1/src/main/java/com/v1/config/SysConfig.java index 2a69f41b..9d56cf9a 100644 --- a/v1/src/main/java/com/v1/config/SysConfig.java +++ b/v1/src/main/java/com/v1/config/SysConfig.java @@ -12,6 +12,9 @@ public class SysConfig { private String wxH5AppId; private String wxH5AppSecret; + private String wxAppId; + private String wxAppSecret; + public String getWxH5AppId() { return wxH5AppId; } @@ -27,4 +30,20 @@ public class SysConfig { public void setWxH5AppSecret(String wxH5AppSecret) { this.wxH5AppSecret = wxH5AppSecret; } + + public String getWxAppId() { + return wxAppId; + } + + public void setWxAppId(String wxAppId) { + this.wxAppId = wxAppId; + } + + public String getWxAppSecret() { + return wxAppSecret; + } + + public void setWxAppSecret(String wxAppSecret) { + this.wxAppSecret = wxAppSecret; + } } diff --git a/v1/src/main/java/com/v1/controller/WxMsgController.java b/v1/src/main/java/com/v1/controller/WxMsgController.java index 4b045b25..0ca5e952 100644 --- a/v1/src/main/java/com/v1/controller/WxMsgController.java +++ b/v1/src/main/java/com/v1/controller/WxMsgController.java @@ -7,7 +7,9 @@ import com.hai.common.exception.SysCode; import com.hai.common.pay.util.IOUtil; import com.hai.common.pay.util.XmlUtil; import com.hai.common.utils.HttpsUtils; +import com.hai.common.utils.RedisUtil; import com.hai.common.utils.ResponseMsgUtil; +import com.hai.common.utils.WxUtils; import com.hai.config.CommonSysConst; import com.hai.model.HighMerchantStoreModel; import com.hai.model.ResponseData; @@ -32,10 +34,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.SortedMap; +import java.util.*; /** * @author sum1dream @@ -54,6 +53,9 @@ public class WxMsgController { @Resource private HighMerchantStoreService merchantStoreService; + @Resource + private RedisUtil redisUtil; + // @RequestMapping(value = "/verifyWxToken", method = RequestMethod.GET) // @ResponseBody // @ApiOperation(value = "验证servlet") @@ -249,5 +251,69 @@ public class WxMsgController { } } + @RequestMapping(value = "/verifyWx", method = RequestMethod.GET) + @ResponseBody + @ApiOperation(value = "微信签名") + public ResponseData verifyWx(@RequestParam(value = "url", required = true) String url) { + + try { + + // 获取access_token + Map params = new HashMap<>(); + params.put("appid", SysConst.getSysConfig().getWxH5AppId()); + params.put("secret", SysConst.getSysConfig().getWxH5AppSecret()); + params.put("grant_type", "client_credential"); + JSONObject accessTokenObject = HttpsUtils.doGet("https://api.weixin.qq.com/cgi-bin/token", params); + + // 获取ticket + Map ticketParams = new HashMap<>(); + ticketParams.put("access_token", accessTokenObject.getString("access_token")); + ticketParams.put("type", "jsapi"); + JSONObject jsapiTicket = HttpsUtils.doGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket", ticketParams); + // 拼接签名 + Map map = new HashMap<>(); + map.put("noncestr", WxUtils.makeNonStr()); +// map.put("jsapi_ticket",jsapiTicket.getString("ticket")); + map.put("jsapi_ticket", "HoagFKDcsGMVCIY2vOjf9jCRQE4yNsjboV-7GnEBJ1lr2n3gsufcHe86CADtZut8goQ7LBktBWIdsZ-AlVthmw"); + map.put("timestamp", new Date().getTime()); + map.put("url",url); + + Map objectMap = new HashMap<>(); + objectMap.put("appId" , SysConst.getSysConfig().getWxH5AppId()); + objectMap.put("timestamp" , map.get("timestamp")); + objectMap.put("nonceStr" , map.get("noncestr")); + objectMap.put("signature" , WxUtils.getSHA1(map)); + + return ResponseMsgUtil.success(objectMap); + } catch (Exception e) { + return null; + } + + } + + @RequestMapping(value = "/getScheme", method = RequestMethod.GET) + @ResponseBody + @ApiOperation(value = "获取小程序scheme码") + public ResponseData getSchemeCode() { + + try { + + // 获取access_token + Map params = new HashMap<>(); + params.put("appid", SysConst.getSysConfig().getWxAppId()); + params.put("secret", SysConst.getSysConfig().getWxAppSecret()); + params.put("grant_type", "client_credential"); + JSONObject accessTokenObject = HttpsUtils.doGet("https://api.weixin.qq.com/cgi-bin/token", params); + + JSONObject postObject = new JSONObject(); + postObject.put("expire_type" ,1); + postObject.put("expire_interval" ,30); + JSONObject object = HttpsUtils.doPost("https://api.weixin.qq.com/wxa/generate_urllink?access_token=" + accessTokenObject.getString("access_token"), postObject); + return ResponseMsgUtil.success(object); + } catch (Exception e) { + return null; + } + + } } diff --git a/v1/src/main/resources/dev/application.yml b/v1/src/main/resources/dev/application.yml index d86cbae9..ee2d1297 100644 --- a/v1/src/main/resources/dev/application.yml +++ b/v1/src/main/resources/dev/application.yml @@ -50,7 +50,7 @@ spring: #客户端id(不能重复) # client: # id: provider-id - #MQTT默认的消息推送主题,实际可在调用接口是指定 + #MQTT默认的消息推送主题,实际可在调用接口是指定 # default: # topic: topic #配置日期返回至前台为时间戳 @@ -59,7 +59,7 @@ spring: write-dates-as-timestamps: true mybatis: mapperLocations: - - classpath*:sqlmap*/*.xml + - classpath*:sqlmap*/*.xml type-aliases-package: org.springboot.sample.entity diff --git a/v1/src/main/resources/dev/config.properties b/v1/src/main/resources/dev/config.properties index b7bbc8e8..39cffecb 100644 --- a/v1/src/main/resources/dev/config.properties +++ b/v1/src/main/resources/dev/config.properties @@ -1,2 +1,5 @@ wxH5AppId=wxa075e8509802f826 wxH5AppSecret=0e606fc1378d35e359fcf3f15570b2c5 + +wxAppId=wx8d49e2f83025229d +wxAppSecret=d8d6dcaef77d3b659258a01b5ddba5df