| @@ -164,6 +164,12 @@ public class WxConsts { | |||||
| * 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 | * 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 | ||||
| */ | */ | ||||
| public static final String OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo"; | public static final String OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo"; | ||||
| /** | |||||
| * 网页应用登录授权作用域 snsapi_login | |||||
| */ | |||||
| public static final String QRCONNECT_SCOPE_SNSAPI_LOGIN = "snsapi_login"; | |||||
| /////////////////////// | /////////////////////// | ||||
| // 永久素材类型 | // 永久素材类型 | ||||
| /////////////////////// | /////////////////////// | ||||
| @@ -152,6 +152,20 @@ public interface WxMpService { | |||||
| */ | */ | ||||
| WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; | WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; | ||||
| /** | |||||
| * <pre> | |||||
| * 构造第三方使用网站应用授权登录的url | |||||
| * 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN">网站应用微信登录开发指南</a> | |||||
| * URL格式为:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect | |||||
| * </pre> | |||||
| * | |||||
| * @param redirectURI 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode | |||||
| * @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 | |||||
| * @param state 非必填,用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 | |||||
| * @return url | |||||
| */ | |||||
| String buildQrConnectUrl(String redirectURI, String scope, String state); | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 构造oauth2授权的url连接 | * 构造oauth2授权的url连接 | ||||
| @@ -282,6 +282,23 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| return url.toString(); | return url.toString(); | ||||
| } | } | ||||
| @Override | |||||
| public String buildQrConnectUrl(String redirectURI, String scope, | |||||
| String state) { | |||||
| StringBuilder url = new StringBuilder(); | |||||
| url.append("https://open.weixin.qq.com/connect/qrconnect?"); | |||||
| url.append("appid=").append(this.wxMpConfigStorage.getAppId()); | |||||
| url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI)); | |||||
| url.append("&response_type=code"); | |||||
| url.append("&scope=").append(scope); | |||||
| if (state != null) { | |||||
| url.append("&state=").append(state); | |||||
| } | |||||
| url.append("#wechat_redirect"); | |||||
| return url.toString(); | |||||
| } | |||||
| private WxMpOAuth2AccessToken getOAuth2AccessToken(StringBuilder url) throws WxErrorException { | private WxMpOAuth2AccessToken getOAuth2AccessToken(StringBuilder url) throws WxErrorException { | ||||
| try { | try { | ||||
| RequestExecutor<String, String> executor = new SimpleGetRequestExecutor(); | RequestExecutor<String, String> executor = new SimpleGetRequestExecutor(); | ||||
| @@ -44,6 +44,7 @@ public class ApiTestModule implements Module { | |||||
| private String openId; | private String openId; | ||||
| private String kfAccount; | private String kfAccount; | ||||
| private String qrconnectRedirectUrl; | |||||
| public String getOpenId() { | public String getOpenId() { | ||||
| return this.openId; | return this.openId; | ||||
| @@ -66,6 +67,14 @@ public class ApiTestModule implements Module { | |||||
| this.kfAccount = kfAccount; | this.kfAccount = kfAccount; | ||||
| } | } | ||||
| public String getQrconnectRedirectUrl() { | |||||
| return this.qrconnectRedirectUrl; | |||||
| } | |||||
| public void setQrconnectRedirectUrl(String qrconnectRedirectUrl) { | |||||
| this.qrconnectRedirectUrl = qrconnectRedirectUrl; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -23,7 +23,7 @@ public class WxMpMiscAPITest { | |||||
| @Test | @Test | ||||
| public void testGetCallbackIP() throws WxErrorException { | public void testGetCallbackIP() throws WxErrorException { | ||||
| String[] ipArray = wxService.getCallbackIP(); | |||||
| String[] ipArray = this.wxService.getCallbackIP(); | |||||
| System.out.println(Arrays.toString(ipArray)); | System.out.println(Arrays.toString(ipArray)); | ||||
| Assert.assertNotNull(ipArray); | Assert.assertNotNull(ipArray); | ||||
| Assert.assertNotEquals(ipArray.length, 0); | Assert.assertNotEquals(ipArray.length, 0); | ||||
| @@ -0,0 +1,162 @@ | |||||
| package me.chanjar.weixin.mp.api.impl; | |||||
| import org.testng.annotations.Guice; | |||||
| import org.testng.annotations.Test; | |||||
| import com.google.inject.Inject; | |||||
| import me.chanjar.weixin.common.api.WxConsts; | |||||
| import me.chanjar.weixin.mp.api.ApiTestModule; | |||||
| import me.chanjar.weixin.mp.api.ApiTestModule.WxXmlMpInMemoryConfigStorage; | |||||
| import org.testng.Assert; | |||||
| @Test | |||||
| @Guice(modules = ApiTestModule.class) | |||||
| public class WxMpServiceImplTest { | |||||
| @Inject | |||||
| private WxMpServiceImpl wxService; | |||||
| @Test | |||||
| public void testCheckSignature() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testGetAccessToken() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testGetAccessTokenBoolean() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testGetJsapiTicket() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testGetJsapiTicketBoolean() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testCreateJsapiSignature() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testCustomMessageSend() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testMassNewsUpload() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testMassVideoUpload() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testMassGroupMessageSend() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testMassOpenIdsMessageSend() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testMassMessagePreview() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testShortUrl() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testTemplateSend() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testSetIndustry() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testGetIndustry() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testSemanticQuery() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testOauth2buildAuthorizationUrl() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testBuildQrConnectUrl() { | |||||
| String qrConnectUrl = this.wxService | |||||
| .buildQrConnectUrl( | |||||
| ((WxXmlMpInMemoryConfigStorage) this.wxService | |||||
| .getWxMpConfigStorage()).getOauth2redirectUri(), | |||||
| WxConsts.QRCONNECT_SCOPE_SNSAPI_LOGIN, null); | |||||
| Assert.assertNotNull(qrConnectUrl); | |||||
| System.out.println(qrConnectUrl); | |||||
| } | |||||
| @Test | |||||
| public void testOauth2getAccessToken() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testOauth2refreshAccessToken() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testOauth2getUserInfo() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testOauth2validateAccessToken() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testGetCallbackIP() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testGet() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testPost() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| @Test | |||||
| public void testExecute() { | |||||
| Assert.fail("Not yet implemented"); | |||||
| } | |||||
| } | |||||
| @@ -7,5 +7,6 @@ | |||||
| <expiresTime>可以不填写</expiresTime> | <expiresTime>可以不填写</expiresTime> | ||||
| <openId>某个加你公众号的用户的openId</openId> | <openId>某个加你公众号的用户的openId</openId> | ||||
| <oauth2redirectUri>网页授权获取用户信息回调地址</oauth2redirectUri> | <oauth2redirectUri>网页授权获取用户信息回调地址</oauth2redirectUri> | ||||
| <qrconnectRedirectUrl>网页应用授权登陆回调地址</qrconnectRedirectUrl> | |||||
| <kfAccount>完整客服账号,格式为:账号前缀@公众号微信号</kfAccount> | <kfAccount>完整客服账号,格式为:账号前缀@公众号微信号</kfAccount> | ||||
| </xml> | </xml> | ||||