第三方组件开发授权流程改变

This commit is contained in:
jinyu 2017-08-13 20:43:18 +08:00
parent bee75e55cf
commit 14327509c7
10 changed files with 171 additions and 85 deletions

View File

@ -26,6 +26,7 @@ import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.type.IdType;
import com.foxinmy.weixin4j.type.TradeType;
import com.foxinmy.weixin4j.type.mch.BillType;
import com.foxinmy.weixin4j.type.mch.RefundAccountType;
import com.foxinmy.weixin4j.util.Consts;
/**
@ -44,11 +45,11 @@ public class PayTest {
static {
ACCOUNT = new WeixinPayAccount(
"appid",
"paysignKey",
"mchId",
"证书密码,为空取mchid",
"证书路径,绝对路径&classpath路径/path/to/certificate.p12,或者填写classpath:path/to/certificate.p12");
"wx7ca5ae77b3b4bc81",
"GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ",
"1290664601",
"1290664601",
"/Users/jy/workspaces/jdxg-parent/ixi-service/src/main/resources/1290664601.p12");
SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey());
PAY = new WeixinPayProxy(ACCOUNT);
}
@ -86,7 +87,7 @@ public class PayTest {
@Test
public void downbill() throws WeixinException, IOException {
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2016);
c.set(Calendar.YEAR, 2012);
c.set(Calendar.MONTH, 3);
c.set(Calendar.DAY_OF_MONTH, 4);
System.err.println(c.getTime());
@ -99,7 +100,7 @@ public class PayTest {
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
RefundResult result = PAY.applyRefund(idQuery,
"TT_R" + System.currentTimeMillis(), 0.01d, 0.01d, null,
"10020674", null);
"10020674", RefundAccountType.REFUND_SOURCE_RECHARGE_FUNDS);
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
System.err.println(result);

View File

@ -2,7 +2,6 @@ package com.foxinmy.weixin4j.example.server.handler;
import org.springframework.stereotype.Component;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
import com.foxinmy.weixin4j.message.TextMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;

View File

@ -210,20 +210,5 @@ public class WeixinComponentProxy {
return "";
}
/**
* 创建WeixinProxy对象
*
* @param componentId
* 组件ID
* @param authAppId
* 已授权的appid
* @see com.foxinmy.weixin4j.mp.WeixinProxy
* @return
*/
public WeixinProxy getWeixinProxy(String componentId, String authAppId) {
return new WeixinProxy(component(componentId).getRefreshTokenManager(
authAppId), component(componentId).getTokenManager());
}
public final static String VERSION = "1.7.7";
}

View File

@ -188,23 +188,6 @@ public class WeixinProxy {
this(weixinAccount, new WeixinTokenCreator(weixinAccount.getId(), weixinAccount.getSecret()), cacheStorager);
}
/**
* 第三方组件方式创建微信接口实现(永久刷新令牌机制)
*
* @param perTicketManager
* 第三方组件永久刷新token
* @param componentTokenManager
* 第三方组件凭证token
* @see com.foxinmy.weixin4j.mp.api.ComponentApi
* @see com.foxinmy.weixin4j.mp.api.ComponentApi#getPerCodeManager(String)
* @see com.foxinmy.weixin4j.mp.api.ComponentApi#getTokenManager
*/
public WeixinProxy(PerTicketManager perTicketManager, TokenManager componentTokenManager) {
this(new WeixinAccount(perTicketManager.getThirdId(), perTicketManager.getThirdSecret()),
new WeixinTokenComponentCreator(perTicketManager, componentTokenManager),
perTicketManager.getCacheStorager());
}
/**
* 微信接口实现
*

View File

@ -11,17 +11,15 @@ import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.ApiResult;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.component.WeixinComponentPreCodeCreator;
import com.foxinmy.weixin4j.mp.component.WeixinComponentTokenCreator;
import com.foxinmy.weixin4j.mp.component.WeixinTokenComponentCreator;
import com.foxinmy.weixin4j.mp.model.AuthorizerOption;
import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.mp.model.AuthorizerOption.AuthorizerOptionName;
import com.foxinmy.weixin4j.mp.model.ComponentAuthInfo;
import com.foxinmy.weixin4j.mp.model.ComponentAuthorizer;
import com.foxinmy.weixin4j.mp.model.ComponentAuthorizerToken;
import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.token.PerTicketManager;
import com.foxinmy.weixin4j.token.TicketManager;
import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.Consts;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
@ -221,12 +219,12 @@ public class ComponentApi extends MpApi {
* 授权code
* @return 第三方组件授权信息
* @see {@link com.foxinmy.weixin4j.mp.WeixinComponentProxy#getComponentAuthorizeURL(String, String, String)}
* @see com.foxinmy.weixin4j.mp.model.ComponentAuthInfo
* @see com.foxinmy.weixin4j.mp.model.ComponentAuthorizerToken
* @throws WeixinException
*/
public ComponentAuthInfo exchangeAuthInfo(String authCode)
public ComponentAuthorizerToken exchangeAuthorizerToken(String authCode)
throws WeixinException {
String component_exchange_authorizer_uri = getRequestUri("component_exchange_authorizer_uri");
String component_exchange_authorizer_uri = getRequestUri("component_query_authorization_uri");
JSONObject obj = new JSONObject();
obj.put("component_appid", ticketManager.getThirdId());
obj.put("authorization_code", authCode);
@ -241,22 +239,45 @@ public class ComponentApi extends MpApi {
privileges.add(privilegesObj.getJSONObject(i)
.getJSONObject("funcscope_category").getInteger("id"));
}
ComponentAuthInfo info = new ComponentAuthInfo();
info.setPrivileges(privileges);
info.setAppId(authObj.getString("authorizer_appid"));
// 微信授权公众号的永久刷新令牌
PerTicketManager perTicketManager = getRefreshTokenManager(info
.getAppId());
// 缓存微信公众号的access_token
TokenCreator tokenCreator = new WeixinTokenComponentCreator(
perTicketManager, tokenManager);
Token token = new Token(authObj.getString("authorizer_access_token"),
authObj.getLongValue("expires_in") * 1000l);
ticketManager.getCacheStorager().caching(tokenCreator.key(), token);
// 缓存微信公众号的永久授权码(refresh_token)
perTicketManager.cachingTicket(authObj
.getString("authorizer_refresh_token"));
return info;
ComponentAuthorizerToken token = new ComponentAuthorizerToken(
authObj.getString("authorizer_access_token"),
authObj.getLongValue("expires_in"));
token.setRefreshToken(authObj.getString("authorizer_refresh_token"));
token.setPrivileges(privileges);
token.setAppId(authObj.getString("authorizer_appid"));
return token;
}
/**
* 获取刷新授权公众号或小程序的接口调用凭据令牌
*
* @param authAppId
* 授权方appid
* @param authRefreshToken
* 授权方的刷新令牌刷新令牌主要用于第三方平台获取和刷新已授权用户的access_token只会在授权时刻提供请妥善保存
* 一旦丢失只能让用户重新授权才能再次拿到新的刷新令牌
* @return 第三方组件授权信息
* @see {@link exchangeAuthInfo(String)}
* @see com.foxinmy.weixin4j.mp.model.ComponentAuthorizerToken
* @throws WeixinException
*/
public ComponentAuthorizerToken refreshAuthorizerToken(String authAppId,
String authRefreshToken) throws WeixinException {
String component_refresh_authorizer_token_uri = getRequestUri("component_refresh_authorizer_token_uri");
JSONObject obj = new JSONObject();
obj.put("component_appid", ticketManager.getThirdId());
obj.put("authorizer_appid", authAppId);
obj.put("authorizer_refresh_token", authRefreshToken);
WeixinResponse response = weixinExecutor.post(String.format(
component_refresh_authorizer_token_uri,
tokenManager.getAccessToken()), obj.toJSONString());
obj = response.getAsJson();
ComponentAuthorizerToken token = new ComponentAuthorizerToken(
obj.getString("authorizer_access_token"),
obj.getLongValue("expires_in"));
token.setRefreshToken(obj.getString("authorizer_refresh_token"));
token.setAppId(authAppId);
return token;
}
/**
@ -267,10 +288,10 @@ public class ComponentApi extends MpApi {
* @param authAppId
* 授权方appid
* @return 第三方组件授权信息
* @see com.foxinmy.weixin4j.mp.model.ComponentAuthInfo
* @see com.foxinmy.weixin4j.mp.model.ComponentAuthorizer
* @throws WeixinException
*/
public ComponentAuthInfo getAuthInfo(String authAppId)
public ComponentAuthorizer getAuthorizerInfo(String authAppId)
throws WeixinException {
String component_get_authorizer_uri = getRequestUri("component_get_authorizer_uri");
JSONObject obj = new JSONObject();
@ -281,12 +302,12 @@ public class ComponentApi extends MpApi {
tokenManager.getAccessToken()), obj.toJSONString());
obj = response.getAsJson();
JSONObject auth = obj.getJSONObject("authorizer_info");
ComponentAuthInfo info = JSON.toJavaObject(auth,
ComponentAuthInfo.class);
info.setServiceType(auth.getJSONObject("service_type_info")
ComponentAuthorizer authorizer = JSON.toJavaObject(auth,
ComponentAuthorizer.class);
authorizer.setServiceType(auth.getJSONObject("service_type_info")
.getIntValue("id"));
authorizer.setVerifyType(auth.getJSONObject("verify_type_info")
.getIntValue("id"));
info.setVerifyType(auth.getJSONObject("verify_type_info").getIntValue(
"id"));
auth = obj.getJSONObject("authorization_info");
JSONArray privilegesObj = auth.getJSONArray("func_info");
List<Integer> privileges = new ArrayList<Integer>(privilegesObj.size());
@ -294,9 +315,9 @@ public class ComponentApi extends MpApi {
privileges.add(privilegesObj.getJSONObject(i)
.getJSONObject("funcscope_category").getInteger("id"));
}
info.setPrivileges(privileges);
info.setAppId(auth.getString("appid"));
return info;
authorizer.setPrivileges(privileges);
authorizer.setAppId(auth.getString("appid"));
return authorizer;
}
/**

View File

@ -221,9 +221,11 @@ card_member_card_user_info_uri={api_base_url}/card/membercard/userinfo/get?acces
card_member_card_update_user_uri={api_base_url}/card/membercard/updateuser?access_token=%s
# \u4f7f\u7528\u6388\u6743\u7801\u6362\u53d6\u516c\u4f17\u53f7\u7684\u63a5\u53e3\u8c03\u7528\u51ed\u636e\u548c\u6388\u6743\u4fe1\u606f
component_exchange_authorizer_uri={api_cgi_url}/component/api_query_auth?component_access_token=%s
component_query_authorization_uri={api_cgi_url}/component/api_query_auth?component_access_token=%s
# \u83b7\u53d6\u6388\u6743\u65b9\u7684\u516c\u4f17\u53f7\u5e10\u53f7\u57fa\u672c\u4fe1\u606f
component_get_authorizer_uri={api_cgi_url}/component/api_get_authorizer_info?component_access_token=%s
# \u83b7\u53d6\uff08\u5237\u65b0\uff09\u6388\u6743\u516c\u4f17\u53f7\u6216\u5c0f\u7a0b\u5e8f\u7684\u63a5\u53e3\u8c03\u7528\u51ed\u636e\uff08\u4ee4\u724c\uff09
component_refresh_authorizer_token_uri={api_cgi_url}/component/api_authorizer_token?component_access_token=%s
# \u83b7\u53d6\u6388\u6743\u65b9\u7684\u9009\u9879\u8bbe\u7f6e\u4fe1\u606f
component_get_authorizer_option_uri={api_cgi_url}/component/api_get_authorizer_option?component_access_token=%s
# \u8bbe\u7f6e\u6388\u6743\u65b9\u7684\u9009\u9879\u4fe1\u606f

View File

@ -8,12 +8,12 @@ import com.alibaba.fastjson.annotation.JSONField;
/**
* 第三方组件授权信息
*
* @className ComponentAuthInfo
* @className ComponentAuthorizer
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月5日
* @since JDK 1.6
*/
public class ComponentAuthInfo implements Serializable {
public class ComponentAuthorizer implements Serializable {
private static final long serialVersionUID = -3610172415045923599L;
/**
* 授权方appId
@ -68,6 +68,12 @@ public class ComponentAuthInfo implements Serializable {
@JSONField(deserialize = false)
private List<Integer> privileges;
/**
* 公众号的主体名称
*/
@JSONField(name = "principal_name")
private String principalName;
public String getAppId() {
return appId;
}
@ -148,13 +154,22 @@ public class ComponentAuthInfo implements Serializable {
this.privileges = privileges;
}
public String getPrincipalName() {
return principalName;
}
public void setPrincipalName(String principalName) {
this.principalName = principalName;
}
@Override
public String toString() {
return "ComponentAuthInfo [nickName=" + nickName + ", headImg="
+ headImg + ", serviceType=" + serviceType + ", verifyType="
+ verifyType + ", userName=" + userName + ", alias=" + alias
+ ", qrcodeUrl=" + qrcodeUrl + ", businessInfo=" + businessInfo
+ ", privileges=" + privileges + "]";
return "ComponentAuthInfo [nickName=" + nickName + ", principalName="
+ principalName + ", headImg=" + headImg + ", serviceType="
+ serviceType + ", verifyType=" + verifyType + ", userName="
+ userName + ", alias=" + alias + ", qrcodeUrl=" + qrcodeUrl
+ ", businessInfo=" + businessInfo + ", privileges="
+ privileges + "]";
}
public static class BusinessInfo implements Serializable {

View File

@ -0,0 +1,70 @@
package com.foxinmy.weixin4j.mp.model;
import java.util.List;
import com.foxinmy.weixin4j.model.Token;
/**
* 授权码换取公众号的授权信息
*
* @className ComponentAuthorizerToken
* @author jinyu(foxinmy@gmail.com)
* @date 2017年8月13日
* @since JDK 1.7
* @see
*/
public class ComponentAuthorizerToken extends Token {
private static final long serialVersionUID = 1L;
/**
* 授权方appid
*/
private String appId;
/**
* 接口调用凭据刷新令牌在授权的公众号具备API权限时才有此返回值刷新令牌主要用于第三方平台获取和刷新已授权用户的access_token
* 只会在授权时刻提供请妥善保存 一旦丢失只能让用户重新授权才能再次拿到新的刷新令牌
*/
private String refreshToken;
/**
* 公众号授权给开发者的权限集列表ID为1到15时分别代表 消息管理权限 用户管理权限 帐号服务权限 网页服务权限 微信小店权限 微信多客服权限
* 群发与通知权限 微信卡券权限 微信扫一扫权限 微信连WIFI权限 素材管理权限 微信摇周边权限 微信门店权限 微信支付权限 自定义菜单权限
*/
private List<Integer> privileges;
public ComponentAuthorizerToken(String accessToken, long expires) {
super(accessToken, expires);
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public List<Integer> getPrivileges() {
return privileges;
}
public void setPrivileges(List<Integer> categoryIds) {
this.privileges = categoryIds;
}
@Override
public String toString() {
return "ComponentAuthorizerToken [appId=" + appId + ", refreshToken="
+ refreshToken + ", privileges=" + privileges + ", "
+ super.toString() + "]";
}
}

View File

@ -15,7 +15,7 @@ public enum IndustryType {
ITKEJI_HULIANWANG$DIANZISHANGWU("IT科技", "互联网|电子商务", 1), ITKEJI_ITRUANJIANYUFUWU(
"IT科技", "IT软件与服务", 2), ITKEJI_ITYINGJIANYUSHEBEI("IT科技", "IT硬件与设备",
3), ITKEJI_DIANZIJISHU("IT科技", "电子技术", 4), ITKEJI_TONGXINYUYUNYINGSHANG(
"IT科技", "通信与运营商", 5), ITKEJI_WANGLUOYOUXI("IT科技", "网络游戏", 6), JINRONGYE_YINXING(
"IT科技", "通信与运营商", 5), ITKEJI_WANGLUOYOUXI("IT科技", "网络游戏", 6), JINRONGYE_YINHANG(
"金融业", "银行", 7), JINRONGYE_JIJIN$LICAI$XINTUO("金融业", "基金|理财|信托", 8), JINRONGYE_BAOXIAN(
"金融业", "保险", 9), CANYIN_CANYIN("餐饮", "餐饮", 10), JIUDIANLUYOU_JIUDIAN(
"酒店旅游", "酒店", 11), JIUDIANLUYOU_LUYOU("酒店旅游", "旅游", 12), YUNSHUYUCANGCHU_KUAIDI(

View File

@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.qy.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Assert;
@ -11,6 +12,7 @@ import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.media.MediaDownloadResult;
import com.foxinmy.weixin4j.model.media.MediaUploadResult;
import com.foxinmy.weixin4j.qy.WeixinProxy;
import com.foxinmy.weixin4j.qy.api.MediaApi;
import com.foxinmy.weixin4j.type.MediaType;
@ -73,4 +75,12 @@ public class MediaTest extends TokenTest {
"19pXNIq8cd69QLwfsLaoZFfS2K82WCHNGPREO--o1rEMlNIOf0N9IDDQdler08S7fNAFsG-5XYwxf1gzORxDnlQ");
System.err.println(result);
}
public static void main(String[] args) throws FileNotFoundException, WeixinException{
WeixinProxy proxy = new WeixinProxy();
File file = new File("/Users/jy/Downloads/weixin4j.png");
String mediaResult = proxy.uploadImage(
new FileInputStream(file), file.getName());
System.out.println(mediaResult);
}
}