WeChatService.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package com.caimei.components;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.caimei.model.ResponseJson;
  5. import com.caimei.util.HttpRequest;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.apache.commons.codec.binary.Base64;
  8. import org.apache.commons.lang.StringUtils;
  9. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.beans.factory.annotation.Value;
  12. import org.springframework.http.HttpHeaders;
  13. import org.springframework.stereotype.Component;
  14. import javax.crypto.Cipher;
  15. import javax.crypto.spec.IvParameterSpec;
  16. import javax.crypto.spec.SecretKeySpec;
  17. import java.security.AlgorithmParameters;
  18. import java.security.Security;
  19. import java.util.HashMap;
  20. import java.util.Map;
  21. /**
  22. * 微信 服务工具类
  23. *
  24. * @author : Charles
  25. * @date : 2021/3/9
  26. */
  27. @Slf4j
  28. @Component
  29. public class WeChatService {
  30. @Value("${wx.AppId}")
  31. private String heHeAppId;
  32. @Value("${wx.AppSecret}")
  33. private String heHeAppSecret;
  34. /*private RedisService redisService;
  35. @Autowired
  36. public void setRedisService(RedisService redisService) {
  37. this.redisService = redisService;
  38. }*/
  39. public static class Keys {
  40. public static final String OPEN_ID = "openid";
  41. public static final String UNION_ID = "unionid";
  42. public static final String SESSION_KEY = "session_key";
  43. }
  44. static {
  45. // BouncyCastle是一个开源的加解密解决方案
  46. Security.addProvider(new BouncyCastleProvider());
  47. }
  48. /**
  49. * AES解密
  50. *
  51. * @param data 密文,被加密的数据
  52. * @param key 秘钥
  53. * @param iv 偏移量
  54. * @param encodingFormat 解密后的结果需要进行的编码
  55. * @return 解密结果
  56. */
  57. public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception {
  58. // 被加密的数据
  59. byte[] dataByte = Base64.decodeBase64(data);
  60. // 加密秘钥
  61. byte[] keyByte = Base64.decodeBase64(key);
  62. // 偏移量
  63. byte[] ivByte = Base64.decodeBase64(iv);
  64. try {
  65. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
  66. SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
  67. AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
  68. parameters.init(new IvParameterSpec(ivByte));
  69. // 初始化
  70. cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
  71. byte[] resultByte = cipher.doFinal(dataByte);
  72. if (null != resultByte && resultByte.length > 0) {
  73. return new String(resultByte, encodingFormat);
  74. }
  75. return null;
  76. } catch (Exception e) {
  77. e.printStackTrace();
  78. }
  79. return null;
  80. }
  81. /**
  82. * 小程序微信授权登录,获取openid
  83. *
  84. * @param code 微信凭证
  85. * @param headers HttpHeaders
  86. * @param mode 1:采美小程序,2:收款工具小程序appId
  87. * @return HashMap
  88. */
  89. public ResponseJson<Map<String, Object>> getInfoMapByApplets(String code, HttpHeaders headers, Integer mode) {
  90. log.info("Start get SessionKey");
  91. Map<String, Object> returnMap = new HashMap<>(4);
  92. // 获取当前微信小程序的环境
  93. String referer = headers.getFirst("Referer");
  94. log.info("referer-is----:" + referer);
  95. returnMap.put("referer", referer);
  96. String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
  97. Map<String, String> requestUrlParam = new HashMap<String, String>(4);
  98. // 呵呵商城小程序appId
  99. requestUrlParam.put("appid", heHeAppId);
  100. log.info("呵呵商城appId: ---" + heHeAppId);
  101. // 呵呵商城小程序appSecret
  102. requestUrlParam.put("secret", heHeAppSecret);
  103. // 小程序端返回的code
  104. requestUrlParam.put("js_code", code);
  105. // 默认参数
  106. requestUrlParam.put("grant_type", "authorization_code");
  107. // 发送post请求读取调用微信接口获取openid用户唯一标识
  108. String infos;
  109. try {
  110. infos = HttpRequest.sendPost(requestUrl, requestUrlParam);
  111. } catch (Exception e) {
  112. return ResponseJson.error("服务器内部异常", returnMap);
  113. }
  114. // 解析相应内容(转换成json对象)
  115. JSONObject jsonObject = JSON.parseObject(infos);
  116. String openId = jsonObject.getString(Keys.OPEN_ID);
  117. String unionId = jsonObject.getString(Keys.UNION_ID);
  118. String sessionKey = jsonObject.getString(Keys.SESSION_KEY);
  119. String errCode = jsonObject.getString("errcode");
  120. String errMsg = jsonObject.getString("errmsg");
  121. log.info("openId----->" + openId + ", unionId------>" + unionId);
  122. returnMap.put(Keys.OPEN_ID, openId);
  123. returnMap.put(Keys.UNION_ID, unionId);
  124. returnMap.put(Keys.SESSION_KEY, sessionKey);
  125. boolean errFlag = StringUtils.isNotEmpty(errCode) && ("-1".equals(errCode) || "40029".equals(errCode) || "45011".equals(errCode));
  126. if (errFlag) {
  127. return ResponseJson.error(-1, errMsg, returnMap);
  128. }
  129. return ResponseJson.success(returnMap);
  130. }
  131. /**
  132. * 网页授权登录,通过code获取openid
  133. *
  134. * @param code 微信code
  135. * @param source 来源
  136. * @return
  137. */
  138. public Map<String, Object> getInfoMapByWeb(String code, String source) throws Exception {
  139. String link = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
  140. // 应用唯一标识
  141. link = link.replace("APPID", heHeAppId);
  142. // 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
  143. link = link.replace("SECRET", heHeAppSecret);
  144. // 获取的code参数
  145. link = link.replace("CODE", code);
  146. // 发送授权链接,得到微信用户信息
  147. String result = HttpRequest.sendGet(link);
  148. log.info(result);
  149. Map<String, Object> map = JSONObject.parseObject(result, Map.class);
  150. return map;
  151. }
  152. /**
  153. * 微信公众号获取access_token
  154. *
  155. * @return access_token
  156. */
  157. public String getAccessToken() throws Exception {
  158. // String access_token = String.valueOf(redisService.get("access_token:"+crmAppId));
  159. // // 过期后会得到"null"值,所以需判断字符串"null"
  160. // if (access_token != null && access_token.length() != 0 && !"null".equals(access_token)) {
  161. // return access_token;
  162. // }
  163. String link = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
  164. link = link.replace("APPID", "wx0938e78f38bc203d");
  165. link = link.replace("APPSECRET", "a563dd2c07c9c815a4e697c8b6cb73dc");
  166. String result = HttpRequest.sendGet(link);
  167. log.info("微信公众号获取access_token>>>" + result);
  168. Map<String, Object> map = JSONObject.parseObject(result, Map.class);
  169. String access_token = (String) map.get("access_token");
  170. // // 将token存入redis, access_token的有效期目前为2个小时(redis存1.5小时)
  171. // redisService.set("access_token:"+crmAppId, access_token, 5400L);
  172. return access_token;
  173. }
  174. /**
  175. * 微信公众号获取用户信息
  176. *
  177. * @return
  178. */
  179. public Map<String, Object> getUserInfo(String accessToken, String openId) throws Exception {
  180. String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN";
  181. String userInfo = HttpRequest.sendGet(requestUrl);
  182. log.info("微信公众号授权用户数据>>>>>>>>>>>" + userInfo);
  183. Map<String, Object> map = JSONObject.parseObject(userInfo, Map.class);
  184. return map;
  185. }
  186. /**
  187. * 网页授权登录,获取用户信息(UnionID机制)
  188. */
  189. public Map<String, Object> getUserInfoByWeb(String access_token, String openId) throws Exception {
  190. String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openId;
  191. String userInfo = HttpRequest.sendGet(requestUrl);
  192. Map<String, Object> map = JSONObject.parseObject(userInfo, Map.class);
  193. return map;
  194. }
  195. }