From faac66c57e66384f07d004d8ab012ee1ba0159d3 Mon Sep 17 00:00:00 2001 From: DB <2502523450@qq.com> Date: Thu, 9 May 2024 17:59:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E6=94=BE=E5=B9=B3=E5=8F=B0=E5=9B=9E?= =?UTF-8?q?=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-test.yml | 2 +- .../src/main/resources/application.yml | 2 +- .../backstage/BackstageWxOpenController.java | 111 -------------- .../callback/CallbackWxOpenController.java | 144 ++++++++++++++++++ 4 files changed, 146 insertions(+), 113 deletions(-) create mode 100644 Cpop-Oam/src/main/java/com/cpop/oam/business/controller/callback/CallbackWxOpenController.java diff --git a/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application-test.yml b/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application-test.yml index 792f738..7a27ef9 100644 --- a/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application-test.yml +++ b/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application-test.yml @@ -4,7 +4,7 @@ cpop: profile: /root/Cpop-Oam/upload jwt: #白名单 - white-list: /profile/**,/backstage/login,/doc.html,/webjars/**,/favicon.ico,/v3/api-docs/**,/swagger-ui.html,/swagger-ui/**,/sysCommon/miniSyncBrandAndStore,/easyLearn/callback/*/*,/easyLearn/*,/mini/cardTemplate/*,/website/**,/backstage/wxCp/*,/callback/wxCp/*/registerCode,/callback/easyLearn/**,/cloudCallback/*,/mini/summit/* + white-list: /profile/**,/backstage/login,/doc.html,/webjars/**,/favicon.ico,/v3/api-docs/**,/swagger-ui.html,/swagger-ui/**,/callback/wxOpen/* #拦截 gateway: rsa-keypair: diff --git a/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application.yml b/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application.yml index f9d8b02..aa727cd 100644 --- a/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application.yml +++ b/Cpop-Oam/Cpop-Oam-Web/src/main/resources/application.yml @@ -183,7 +183,7 @@ wx: component-token: jambox component-aes-key: 1a3NBxmCFwkCJvfoQ7WhJHB6iX3qHPsc9JbaDznE1i0 #授权链接 - authorized-link: https://jamboxtest.cpopsz.com/Jambox-System/callback/wxOpen/authorization + authorized-link: https://oamtest.cpopsz.com/Cpop-Oam/callback/wxOpen/authorization redis: host: gz-crs-lv77ii2t.sql.tencentcdb.com port: 27714 diff --git a/Cpop-Oam/src/main/java/com/cpop/oam/business/controller/backstage/BackstageWxOpenController.java b/Cpop-Oam/src/main/java/com/cpop/oam/business/controller/backstage/BackstageWxOpenController.java index 9f2d65e..090d566 100644 --- a/Cpop-Oam/src/main/java/com/cpop/oam/business/controller/backstage/BackstageWxOpenController.java +++ b/Cpop-Oam/src/main/java/com/cpop/oam/business/controller/backstage/BackstageWxOpenController.java @@ -5,7 +5,6 @@ import com.cpop.core.base.entity.PageDomain; import com.cpop.core.base.entity.R; import com.cpop.core.base.exception.ServiceException; import com.cpop.core.utils.SqlUtils; -import com.cpop.core.utils.StringUtils; import com.cpop.oam.business.bo.WxOpenAddToTemplateBo; import com.cpop.oam.business.bo.WxOpenMaCodeCommitBo; import com.cpop.oam.business.bo.WxOpenMaTrialQrCodeBo; @@ -18,14 +17,10 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo; import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitStandardExt; import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage; -import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; import me.chanjar.weixin.open.bean.result.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -59,35 +54,6 @@ public class BackstageWxOpenController { @Autowired private WxOpenMiniService wxOpenMiniService; - /** - * 第三方平台授权 - * @author DB - * @since 2023/10/10 13:43 - * @param requestBody 请求参数 - * @param timestamp 时间戳 - * @param nonce 随机串 - * @param signature 签名 - * @param encType 解密类型 - * @param msgSignature 签名信息 - */ - @RequestMapping("/receiveTicket") - public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp, - @RequestParam("nonce") String nonce, @RequestParam("signature") String signature, - @RequestParam(name = "encrypt_type", required = false) String encType, - @RequestParam(name = "msg_signature", required = false) String msgSignature) { - if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { - throw new ServiceException("非法请求,可能属于伪造的请求!"); - } - // aes加密的消息 - WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); - try { - wxOpenService.getWxOpenComponentService().route(inMessage); - } catch (WxErrorException e) { - log.error("wxOpen:receiveTicket", e); - } - return "success"; - } - /** * 获取授权链接 * @return R @@ -101,83 +67,7 @@ public class BackstageWxOpenController { return R.ok(preAuthUrl); } - /** - * 授权回调地址 - * @author DB - * @since 2023/10/10 15:49 - * @param authorizationCode 授权码 - * @return me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult - */ - @GetMapping("/redirectUrl") - @ResponseBody - public WxOpenQueryAuthResult redirectUrl(@RequestParam("auth_code") String authorizationCode) { - try { - return wxOpenService.getWxOpenComponentService().getQueryAuth(authorizationCode); - } catch (WxErrorException e) { - log.error("gotoPreAuthUrl", e); - throw new ServiceException(e.getMessage()); - } - } - /** - * @author DB - * @since 2023/10/10 14:56 - * @param requestBody 请求体 - * @param appId appid - * @param signature 签名 - * @param timestamp 时间戳 - * @param nonce 随机串 - * @param openid openId - * @param encType 加密类型 - * @param msgSignature 加密信息 - */ - @RequestMapping("/{appId}/callback") - public Object callback(@RequestBody(required = false) String requestBody, - @PathVariable("appId") String appId, - @RequestParam("signature") String signature, - @RequestParam("timestamp") String timestamp, - @RequestParam("nonce") String nonce, - @RequestParam("openid") String openid, - @RequestParam("encrypt_type") String encType, - @RequestParam("msg_signature") String msgSignature) { - if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { - throw new ServiceException("非法请求,可能属于伪造的请求!"); - } - String out = ""; - // aes加密的消息 - WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); - // 全网发布测试用例 - if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) { - try { - if (StringUtils.equals(inMessage.getMsgType(), "text")) { - if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) { - out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml( - WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback") - .fromUser(inMessage.getToUser()) - .toUser(inMessage.getFromUser()) - .build(), - wxOpenService.getWxOpenConfigStorage() - ); - } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) { - String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api"; - WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build(); - wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); - } - } else if (StringUtils.equals(inMessage.getMsgType(), "event")) { - WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build(); - wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); - } - } catch (WxErrorException e) { - log.error("callback", e); - } - }else{ - WxMpXmlOutMessage outMessage = wxOpenService.getWxOpenMessageRouter().route(inMessage, appId); - if(outMessage != null){ - out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, wxOpenService.getWxOpenConfigStorage()); - } - } - return out; - } /** * @param appid 绑定小程序appid @@ -318,7 +208,6 @@ public class BackstageWxOpenController { /** * 提交代码审核 - * @param message 微信小程序代码包提交审核(仅供第三方开发者代小程序调用 * @return R * @author DB * @since 2023/6/16 0016 17:34 diff --git a/Cpop-Oam/src/main/java/com/cpop/oam/business/controller/callback/CallbackWxOpenController.java b/Cpop-Oam/src/main/java/com/cpop/oam/business/controller/callback/CallbackWxOpenController.java new file mode 100644 index 0000000..11d84e7 --- /dev/null +++ b/Cpop-Oam/src/main/java/com/cpop/oam/business/controller/callback/CallbackWxOpenController.java @@ -0,0 +1,144 @@ +package com.cpop.oam.business.controller.callback; + +import com.cpop.core.base.entity.R; +import com.cpop.core.base.exception.ServiceException; +import com.cpop.core.utils.StringUtils; +import com.cpop.oam.framework.handler.wxOpen.WxOpenHandler; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * @author DB + * @version 1.0.0 + * @since 2024-05-08 18:29 + */ +@RestController +@Tag(name = "微信开放平台模块") +@RequestMapping("/callback/wxOpen") +@Slf4j +public class CallbackWxOpenController { + + @Autowired + private WxOpenHandler wxOpenService; + + /** + * 第三方平台授权 + * @author DB + * @since 2023/10/10 13:43 + * @param requestBody 请求参数 + * @param timestamp 时间戳 + * @param nonce 随机串 + * @param signature 签名 + * @param encType 解密类型 + * @param msgSignature 签名信息 + */ + @RequestMapping("/receiveTicket") + public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, @RequestParam("signature") String signature, + @RequestParam(name = "encrypt_type", required = false) String encType, + @RequestParam(name = "msg_signature", required = false) String msgSignature) { + if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { + throw new ServiceException("非法请求,可能属于伪造的请求!"); + } + // aes加密的消息 + WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); + try { + wxOpenService.getWxOpenComponentService().route(inMessage); + } catch (WxErrorException e) { + log.error("wxOpen:receiveTicket", e); + } + return "success"; + } + + /** + * 公众号或小程序授权回调 + * @param authCode 授权码 + * @return R> + * @author DB + * @since 2023/6/14 0014 17:00 + */ + @Operation(summary = "公众号或小程序授权回调") + @GetMapping("/authorization") + public R authorization(@RequestParam(value = "auth_code") String authCode) throws WxErrorException { + WxOpenComponentService wxOpenComponentService = wxOpenService.getWxOpenComponentService(); + //换取信息 + WxOpenQueryAuthResult queryAuth = wxOpenComponentService.getQueryAuth(authCode); + WxOpenAuthorizationInfo authorizationInfo = queryAuth.getAuthorizationInfo(); + //存入缓存 + WxOpenConfigStorage wxOpenConfigStorage = wxOpenService.getWxOpenConfigStorage(); + wxOpenConfigStorage.setAuthorizerRefreshToken(authorizationInfo.getAuthorizerAppid(), authorizationInfo.getAuthorizerRefreshToken()); + return R.ok(); + } + + /** + * @author DB + * @since 2023/10/10 14:56 + * @param requestBody 请求体 + * @param appId appid + * @param signature 签名 + * @param timestamp 时间戳 + * @param nonce 随机串 + * @param openid openId + * @param encType 加密类型 + * @param msgSignature 加密信息 + */ + @RequestMapping("/{appId}/callback") + public Object callback(@RequestBody(required = false) String requestBody, + @PathVariable("appId") String appId, + @RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestParam("openid") String openid, + @RequestParam("encrypt_type") String encType, + @RequestParam("msg_signature") String msgSignature) { + if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { + throw new ServiceException("非法请求,可能属于伪造的请求!"); + } + String out = ""; + // aes加密的消息 + WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); + // 全网发布测试用例 + if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) { + try { + if (StringUtils.equals(inMessage.getMsgType(), "text")) { + if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) { + out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml( + WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback") + .fromUser(inMessage.getToUser()) + .toUser(inMessage.getFromUser()) + .build(), + wxOpenService.getWxOpenConfigStorage() + ); + } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) { + String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api"; + WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build(); + wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); + } + } else if (StringUtils.equals(inMessage.getMsgType(), "event")) { + WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build(); + wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); + } + } catch (WxErrorException e) { + log.error("callback", e); + } + }else{ + WxMpXmlOutMessage outMessage = wxOpenService.getWxOpenMessageRouter().route(inMessage, appId); + if(outMessage != null){ + out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, wxOpenService.getWxOpenConfigStorage()); + } + } + return out; + } +}