|
@@ -0,0 +1,197 @@
|
|
|
|
+package com.caimei365.user.components;
|
|
|
|
+
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.caimei365.user.model.JsonModel;
|
|
|
|
+import com.caimei365.user.utils.RequestUtil;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
|
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
|
+import org.springframework.http.server.reactive.ServerHttpRequest;
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
+import org.springframework.web.server.ServerWebExchange;
|
|
|
|
+
|
|
|
|
+import javax.crypto.Cipher;
|
|
|
|
+import javax.crypto.spec.IvParameterSpec;
|
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
|
+import java.security.AlgorithmParameters;
|
|
|
|
+import java.security.Security;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 微信 服务工具类
|
|
|
|
+ *
|
|
|
|
+ * @author : Charles
|
|
|
|
+ * @date : 2021/3/9
|
|
|
|
+ */
|
|
|
|
+@Slf4j
|
|
|
|
+@Component
|
|
|
|
+public class WeChatService {
|
|
|
|
+ private String redirectUri;
|
|
|
|
+ private String appId;
|
|
|
|
+ private String appSecret;
|
|
|
|
+ private String miniAppId;
|
|
|
|
+ private String miniAppSecret;
|
|
|
|
+ private String crmAppId;
|
|
|
|
+ private String crmAppSecret;
|
|
|
|
+
|
|
|
|
+ @Value("${wx.redirect_uri}")
|
|
|
|
+ public void setRedirectUri(String redirectUri) {
|
|
|
|
+ redirectUri = redirectUri;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Value("${wx.app-id}")
|
|
|
|
+ public void setAppId(String appId) {
|
|
|
|
+ appId = appId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Value("${wx.app-secret}")
|
|
|
|
+ public void setAppSecret(String appSecret) {
|
|
|
|
+ appSecret = appSecret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Value("${wx.mini-app-id}")
|
|
|
|
+ public void setMiniAppId(String miniAppId) {
|
|
|
|
+ miniAppId = miniAppId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Value("${wx.mini-app-secret}")
|
|
|
|
+ public void setMiniAppSecret(String miniAppSecret) {
|
|
|
|
+ miniAppSecret = miniAppSecret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Value("${wx.crm-app-id}")
|
|
|
|
+ public void setCrmAppId(String crmAppId) {
|
|
|
|
+ crmAppId = crmAppId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Value("${wx.crm-app-secret}")
|
|
|
|
+ public void setCrmAppSecret(String crmAppSecret) {
|
|
|
|
+ crmAppSecret = crmAppSecret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getRedirectUri() {
|
|
|
|
+ return redirectUri;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getAppId() {
|
|
|
|
+ return appId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getAppSecret() {
|
|
|
|
+ return appSecret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getMiniAppId() {
|
|
|
|
+ return miniAppId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getMiniAppSecret() {
|
|
|
|
+ return miniAppSecret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getCrmAppId() {
|
|
|
|
+ return crmAppId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getCrmAppSecret() {
|
|
|
|
+ return crmAppSecret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static {
|
|
|
|
+ // BouncyCastle是一个开源的加解密解决方案
|
|
|
|
+ Security.addProvider(new BouncyCastleProvider());
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * AES解密
|
|
|
|
+ *
|
|
|
|
+ * @param data 密文,被加密的数据
|
|
|
|
+ * @param key 秘钥
|
|
|
|
+ * @param iv 偏移量
|
|
|
|
+ * @param encodingFormat 解密后的结果需要进行的编码
|
|
|
|
+ * @return 解密结果
|
|
|
|
+ */
|
|
|
|
+ public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception {
|
|
|
|
+ // 被加密的数据
|
|
|
|
+ byte[] dataByte = Base64.decodeBase64(data);
|
|
|
|
+ // 加密秘钥
|
|
|
|
+ byte[] keyByte = Base64.decodeBase64(key);
|
|
|
|
+ // 偏移量
|
|
|
|
+ byte[] ivByte = Base64.decodeBase64(iv);
|
|
|
|
+ try {
|
|
|
|
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
|
|
|
|
+ SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
|
|
|
|
+ AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
|
|
|
|
+ parameters.init(new IvParameterSpec(ivByte));
|
|
|
|
+ // 初始化
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
|
|
|
|
+ byte[] resultByte = cipher.doFinal(dataByte);
|
|
|
|
+ if (null != resultByte && resultByte.length > 0) {
|
|
|
|
+ return new String(resultByte, encodingFormat);
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 小程序微信授权登录,获取openid
|
|
|
|
+ *
|
|
|
|
+ * @param code 微信凭证
|
|
|
|
+ * @param serverWebExchange ServerWebExchange
|
|
|
|
+ * @return HashMap
|
|
|
|
+ */
|
|
|
|
+ public JsonModel<Map<String, Object>> getAppletsInfo(String code, ServerWebExchange serverWebExchange) {
|
|
|
|
+ log.info("Start get SessionKey");
|
|
|
|
+ Map<String, Object> returnMap = new HashMap<>(4);
|
|
|
|
+ // 获取当前微信小程序的环境
|
|
|
|
+ ServerHttpRequest request = serverWebExchange.getRequest();
|
|
|
|
+ HttpHeaders headers = request.getHeaders();
|
|
|
|
+ String referer = headers.getFirst("Referer");
|
|
|
|
+ log.info("referer-is----:" + referer);
|
|
|
|
+ returnMap.put("referer", referer);
|
|
|
|
+ String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
|
|
|
|
+ Map<String, String> requestUrlParam = new HashMap<String, String>(4);
|
|
|
|
+ // 小程序appId
|
|
|
|
+ requestUrlParam.put("appId", miniAppId);
|
|
|
|
+ log.info("appId: ---" + miniAppId);
|
|
|
|
+ // 小程序appSecret
|
|
|
|
+ requestUrlParam.put("appSecret", miniAppSecret);
|
|
|
|
+ // 小程序端返回的code
|
|
|
|
+ requestUrlParam.put("code", code);
|
|
|
|
+ // 默认参数
|
|
|
|
+ requestUrlParam.put("grantType", "authorization_code");
|
|
|
|
+ // 发送post请求读取调用微信接口获取openid用户唯一标识
|
|
|
|
+ String infos;
|
|
|
|
+ try {
|
|
|
|
+ infos = RequestUtil.sendPost(requestUrl, requestUrlParam);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ return JsonModel.error("服务器内部异常", returnMap);
|
|
|
|
+ }
|
|
|
|
+ // 解析相应内容(转换成json对象)
|
|
|
|
+ JSONObject jsonObject = JSON.parseObject(infos);
|
|
|
|
+ String openId = jsonObject.getString("openid");
|
|
|
|
+ String unionId = jsonObject.getString("unionid");
|
|
|
|
+ String sessionKey = jsonObject.getString("session_key");
|
|
|
|
+ String errCode = jsonObject.getString("errcode");
|
|
|
|
+ String errMsg = jsonObject.getString("errmsg");
|
|
|
|
+ log.info("openId----->" + openId +", unionId------>" + unionId);
|
|
|
|
+ returnMap.put("openId", openId);
|
|
|
|
+ returnMap.put("unionId", unionId);
|
|
|
|
+ returnMap.put("sessionKey", sessionKey);
|
|
|
|
+ boolean errFlag = StringUtils.isNotEmpty(errCode) && ("-1".equals(errCode) || "40029".equals(errCode) || "45011".equals(errCode));
|
|
|
|
+ if (errFlag) {
|
|
|
|
+ return JsonModel.error(-1, errMsg, returnMap);
|
|
|
|
+ }
|
|
|
|
+ return JsonModel.success(returnMap);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|