From a2e82448b835ddb4357ce1932041ddb54c0fc707 Mon Sep 17 00:00:00 2001 From: hywr <33077958+hywr@users.noreply.github.com> Date: Mon, 24 May 2021 11:34:13 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20#2128=20=E3=80=90=E5=BC=80=E6=94=BE?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E3=80=91=20=20=E4=BF=AE=E5=A4=8D=E5=85=AC?= =?UTF-8?q?=E4=BC=97=E5=8F=B7=E5=9C=A8=E7=94=B1=E7=AC=AC=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E7=AE=A1=E7=90=86=E6=97=B6OAuth2Service?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E7=9B=B8=E5=85=B3=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/WxOAuth2Service.java | 4 +- .../service/WxOAuth2ServiceDecorator.java | 16 +++++ .../weixin/mp/api/WxMpGuideTagService.java | 2 + .../mp/api/impl/WxMpGuideTagServiceImpl.java | 2 +- .../open/api/WxOpenComponentService.java | 9 ++- .../api/impl/WxOpenMpOAuth2ServiceImpl.java | 61 ++++++++++++++++++ .../open/api/impl/WxOpenMpServiceImpl.java | 3 +- .../impl/WxOpenMpOAuth2ServiceImplTest.java | 29 +++++++++ .../weixin/open/test/ApiTestModule.java | 64 +++++++++++++++++++ .../weixin/open/test/TestConfigStorage.java | 16 +++++ .../src/test/resources/test-config.sample.xml | 5 +- 11 files changed, 205 insertions(+), 6 deletions(-) create mode 100644 weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2ServiceDecorator.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImpl.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImplTest.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/test/ApiTestModule.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/test/TestConfigStorage.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2Service.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2Service.java index 97a74d2c6..5a53de010 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2Service.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2Service.java @@ -14,11 +14,11 @@ public interface WxOAuth2Service { /** *
    * 构造oauth2授权的url连接.
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息
+   * 详情请见: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
    * 
* * @param redirectUri 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode - * @param scope scope + * @param scope scope,静默:snsapi_base, 带信息授权:snsapi_userinfo * @param state state * @return url */ diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2ServiceDecorator.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2ServiceDecorator.java new file mode 100644 index 000000000..a495dbf82 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOAuth2ServiceDecorator.java @@ -0,0 +1,16 @@ +package me.chanjar.weixin.common.service; + +import lombok.AllArgsConstructor; +import lombok.experimental.Delegate; + +/** + * 微信 oauth2服务 装饰器 + * + * @author 广州跨界 + */ +@AllArgsConstructor +public class WxOAuth2ServiceDecorator implements WxOAuth2Service { + + @Delegate + private final WxOAuth2Service wxOAuth2Service; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGuideTagService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGuideTagService.java index 554815b70..b2bb76d78 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGuideTagService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGuideTagService.java @@ -7,6 +7,8 @@ import me.chanjar.weixin.mp.bean.guide.WxMpGuideTagInfo; import java.util.List; /** + * 微信导购助手(现在叫对话能力)标签相关接口. + * * @author 广州跨界-宋心成 * @date 2021/5/13/013 */ diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGuideTagServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGuideTagServiceImpl.java index 1bde21e9b..2747cbdae 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGuideTagServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGuideTagServiceImpl.java @@ -106,7 +106,7 @@ public class WxMpGuideTagServiceImpl implements WxMpGuideTagService { body.put(ACCOUNT, account); body.put(OPENID, openid); body.put("push_count", pushCount); - body.put("tag_value", value); + body.put("tag_values", value); String returnString = this.mpService.post(WxMpApiUrl.Guide.QUERY_GUIDE_BUYER_BY_TAG, body); return WxGsonBuilder.create().fromJson(GsonParser.parse(returnString).getAsJsonArray("openid_list"), new TypeToken>() { diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index b0faef7a6..26dc2ba7f 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -1,8 +1,9 @@ package me.chanjar.weixin.open.api; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; -import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.open.bean.WxOpenCreateResult; import me.chanjar.weixin.open.bean.WxOpenGetResult; import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; @@ -330,7 +331,10 @@ public interface WxOpenComponentService { * @param code the code * @return the wx mp o auth 2 access token * @throws WxErrorException the wx error exception + * @see WxMpService#getOAuth2Service() + * @deprecated 2021-05-21: 已修正公众号相关接口,请使用:WxOpenCommpentService.getWxMpServiceByAppid(mpAppId).getOAuth2Service().getAccessToken(code) */ + @Deprecated WxOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; /** @@ -362,7 +366,10 @@ public interface WxOpenComponentService { * @param scope the scope * @param state the state * @return the string + * @see WxMpService#getOAuth2Service() + * @deprecated 2021-05-21: 已修正公众号相关接口,请使用:WxOpenCommpentService.getWxMpServiceByAppid(mpAppId).getOAuth2Service().buildAuthorizationUrl(redirectUri, scope, state) */ + @Deprecated String oauth2buildAuthorizationUrl(String appid, String redirectUri, String scope, String state); /** diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImpl.java new file mode 100644 index 000000000..406e36348 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImpl.java @@ -0,0 +1,61 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.service.WxOAuth2Service; +import me.chanjar.weixin.common.service.WxOAuth2ServiceDecorator; +import me.chanjar.weixin.common.util.http.URIUtil; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import org.apache.commons.lang3.StringUtils; + +/** + * 微信 第三方平台对于公众号 oauth2 的实现类 + * + * @author 广州跨界 + */ +public class WxOpenMpOAuth2ServiceImpl extends WxOAuth2ServiceDecorator { + + private final WxOpenComponentService wxOpenComponentService; + private final WxMpConfigStorage wxMpConfigStorage; + + + public WxOpenMpOAuth2ServiceImpl(WxOpenComponentService wxOpenComponentService, WxOAuth2Service wxOAuth2Service, WxMpConfigStorage wxMpConfigStorage) { + super(wxOAuth2Service); + this.wxOpenComponentService = wxOpenComponentService; + this.wxMpConfigStorage = wxMpConfigStorage; + } + + /** + * 第三方平台代公众号发起网页授权 + * 文档地址:https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/Before_Develop/Official_Accounts/official_account_website_authorization.html + * + * @param code 微信授权code + * @return 微信用户信息 + * @throws WxErrorException 如果微信接口调用失败将抛出此异常 + */ + @Override + public WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException { + String url = String.format( + WxOpenComponentService.OAUTH2_ACCESS_TOKEN_URL, + wxMpConfigStorage.getAppId(), + code, + wxOpenComponentService.getWxOpenConfigStorage().getComponentAppId() + ); + String responseContent = wxOpenComponentService.get(url); + return WxOAuth2AccessToken.fromJson(responseContent); + } + + @Override + public String buildAuthorizationUrl(String redirectUri, String scope, String state) { + return String.format( + WxOpenComponentService.CONNECT_OAUTH2_AUTHORIZE_URL, + wxMpConfigStorage.getAppId(), + URIUtil.encodeURIComponent(redirectUri), + scope, + StringUtils.trimToEmpty(state), + wxOpenComponentService.getWxOpenConfigStorage().getComponentAppId() + ); + } +} + diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java index 19e103fa2..8e5531153 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java @@ -10,7 +10,6 @@ import me.chanjar.weixin.open.api.WxOpenMpService; import me.chanjar.weixin.open.bean.mp.FastRegisterResult; import java.net.URLEncoder; -import java.util.HashMap; import java.util.Objects; /** @@ -22,9 +21,11 @@ public class WxOpenMpServiceImpl extends WxMpServiceImpl implements WxOpenMpServ private String appId; public WxOpenMpServiceImpl(WxOpenComponentService wxOpenComponentService, String appId, WxMpConfigStorage wxMpConfigStorage) { +// wxOpenComponentService.oauth2getAccessToken(appId) this.wxOpenComponentService = wxOpenComponentService; this.appId = appId; this.wxMpConfigStorage = wxMpConfigStorage; + setOAuth2Service(new WxOpenMpOAuth2ServiceImpl(wxOpenComponentService, getOAuth2Service(), wxMpConfigStorage)); initHttp(); } diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImplTest.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImplTest.java new file mode 100644 index 000000000..aab7af27d --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenMpOAuth2ServiceImplTest.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.open.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.api.WxOpenMpService; +import me.chanjar.weixin.open.test.ApiTestModule; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +@Guice(modules = ApiTestModule.class) +public class WxOpenMpOAuth2ServiceImplTest { + + @Inject + protected WxOpenMpService wxOpenMpService; + + + @Test + public void buildAuthorizationUrl() { + String url = wxOpenMpService.getOAuth2Service().buildAuthorizationUrl("https://t.aaxp.cn/api/base/mp/showCode", "snsapi_userinfo", ""); + System.out.println(url); + } + + @Test + public void getAccessToken() throws WxErrorException { + WxOAuth2AccessToken result = wxOpenMpService.getOAuth2Service().getAccessToken("041crm0005iFJL1b2l400I0s0k4crm0z"); + System.out.println(result); + } +} diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/test/ApiTestModule.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/test/ApiTestModule.java new file mode 100644 index 000000000..8a3c3b946 --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/test/ApiTestModule.java @@ -0,0 +1,64 @@ +package me.chanjar.weixin.open.test; + +import com.google.inject.Binder; +import com.google.inject.Module; +import com.thoughtworks.xstream.XStream; +import me.chanjar.weixin.common.error.WxRuntimeException; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; +import me.chanjar.weixin.open.api.WxOpenMaService; +import me.chanjar.weixin.open.api.WxOpenMpService; +import me.chanjar.weixin.open.api.WxOpenService; +import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; + +public class ApiTestModule implements Module { + private final Logger log = LoggerFactory.getLogger(this.getClass()); + private static final String TEST_CONFIG_XML = "test-config.xml"; + + @Override + public void configure(Binder binder) { + try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(TEST_CONFIG_XML)) { + if (inputStream == null) { + throw new WxRuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成"); + } + + TestConfigStorage config = this.fromXml(TestConfigStorage.class, inputStream); + WxOpenService service = new WxOpenServiceImpl(); + + service.setWxOpenConfigStorage(config); + + binder.bind(TestConfigStorage.class).toInstance(config); + binder.bind(WxOpenService.class).toInstance(service); + + if (config.getTestMpAppId() != null && !config.getTestMpAppId().isEmpty()) { + //如果配置了测试公众号,则构建公众号服务依赖 + binder.bind(WxOpenMpService.class).toInstance(service.getWxOpenComponentService().getWxMpServiceByAppid(config.getTestMpAppId())); + } else { + log.warn("建议参照参照 test-config-sample.xml 配置测试公众号"); + } + + if (config.getTestMaAppId() != null && !config.getTestMaAppId().isEmpty()) { + //如果配置了测试小程序,则构建小程序服务依赖 + binder.bind(WxOpenMaService.class).toInstance(service.getWxOpenComponentService().getWxMaServiceByAppid(config.getTestMaAppId())); + } else { + log.warn("建议参照参照 test-config-sample.xml 配置测试小程序"); + } + + } catch (IOException e) { + this.log.error(e.getMessage(), e); + } + } + + @SuppressWarnings("unchecked") + private T fromXml(Class clazz, InputStream is) { + XStream xstream = XStreamInitializer.getInstance(); + xstream.alias("xml", clazz); + xstream.processAnnotations(clazz); + return (T) xstream.fromXML(is); + } + +} diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/test/TestConfigStorage.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/test/TestConfigStorage.java new file mode 100644 index 000000000..52e4fa8aa --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/test/TestConfigStorage.java @@ -0,0 +1,16 @@ +package me.chanjar.weixin.open.test; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; + +@Getter +@Setter +@XStreamAlias("xml") +public class TestConfigStorage extends WxOpenInMemoryConfigStorage { + + private String testMpAppId; + + private String testMaAppId; +} diff --git a/weixin-java-open/src/test/resources/test-config.sample.xml b/weixin-java-open/src/test/resources/test-config.sample.xml index 896969e43..f0130d0c8 100644 --- a/weixin-java-open/src/test/resources/test-config.sample.xml +++ b/weixin-java-open/src/test/resources/test-config.sample.xml @@ -1,7 +1,10 @@ 第三方平台appID 第三方平台appsecret + 第三方平台appsecret + 微信服务器推送过来的ticket 第三方平台Token 第三方平台EncodingAESKey - 测试APPID + 测试公众号 + 测试小程序