Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修复公众号在由第三方平台管理时OAuth2Service授权相关报错问题 #2128

Merged
merged 6 commits into from
May 24, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ public interface WxOAuth2Service {
/**
* <pre>
* 构造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
* </pre>
*
* @param redirectUri 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode
* @param scope scope
* @param scope scope,静默:snsapi_base, 带信息授权:snsapi_userinfo
* @param state state
* @return url
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package me.chanjar.weixin.common.service;

import lombok.AllArgsConstructor;
import lombok.experimental.Delegate;

/**
* 微信 oauth2服务 装饰器
*
* @author <a href="https://www.sacoc.cn">广州跨界</a>
*/
@AllArgsConstructor
public class WxOAuth2ServiceDecorator implements WxOAuth2Service {

@Delegate
private final WxOAuth2Service wxOAuth2Service;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import java.util.List;

/**
* 微信导购助手(现在叫对话能力)标签相关接口.
*
* @author <a href="https://www.sacoc.cn">广州跨界-宋心成</a>
* @date 2021/5/13/013
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public List<String> queryGuideBuyerByTag(String account, String openid, Integer
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<List<String>>() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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);

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <a href="https://www.sacoc.cn">广州跨界</a>
*/
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()
);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import me.chanjar.weixin.open.bean.mp.FastRegisterResult;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Objects;

/**
Expand All @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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> T fromXml(Class<T> clazz, InputStream is) {
XStream xstream = XStreamInitializer.getInstance();
xstream.alias("xml", clazz);
xstream.processAnnotations(clazz);
return (T) xstream.fromXML(is);
}

}
Original file line number Diff line number Diff line change
@@ -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;
}
5 changes: 4 additions & 1 deletion weixin-java-open/src/test/resources/test-config.sample.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<xml>
<componentAppId>第三方平台appID</componentAppId>
<componentSecret>第三方平台appsecret</componentSecret>
<componentAppSecret>第三方平台appsecret</componentAppSecret>
<componentVerifyTicket>微信服务器推送过来的ticket</componentVerifyTicket>
<componentToken>第三方平台Token</componentToken>
<componentAesKey>第三方平台EncodingAESKey</componentAesKey>
<appId>测试APPID</appId>
<testMpAppId>测试公众号</testMpAppId>
<testMaAppId>测试小程序</testMaAppId>
</xml>