java微信第三方平台开发(二)
2016-11-15 18:29
561 查看
一、获取公众号的的授权
在申请的第三方平台下填写的开发者资料里有:授权测试公众号列表、授权事件接受的URL,首先要在测试列表里添加:公众号的原始ID,然后在URl地址里用java代码处理微信每10分钟推送过来xml啦,然后的步骤是解析xml,获取component_verify_ticket —> 调用接口获取component_access_token —>获取预授权码pre_auth_code(可存在数据库中) — >回复微信success — >引导用户进去授权页 —>获取authorization_code —>换取authorizer_access_token(它和普通公众号的基础token作用一样,也能获取用户的openId和用户信息)
第三方公众号获取微信推送的xml
handleAuthorize方法用来接受处理xml:
上述用到的加密解密工具类可以点击这里下载使用,这里的WeChatContants.token和encodingAesKey就是在开发者资料填写的token和key。
获取component_verify_ticket(第三方验证的票据)
解析上述解密后的xml文件,获取节点component_verify_ticket内容,后续用来调用微信接口获取第三方通行token.
接上述代码:
调用微信接口获取component_access_token
url:https://api.weixin.qq.com/cgi-bin/component/api_component_token
method:post
type:json
params:
component_appid(第三方公众号appid,第三方公众号创建好后即可知道)、
component_appsecret(第三方公众号的appsecret,同上)、
component_verify_ticket(上步获取到component_verify_ticket)
接上述代码:
第三方公众号获取预授权码pre_auth_code
url地址:
https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token={0}
method:post
type:json
params:
component_appid:第三方平台公众号appid
解析json,并将component_access_token存在数据库中,用来授权时使用。
接上述代码:
引导普通公众号进入授权页面进行扫码授权
从数据库中获取上步存入的预授权码:pre_auth_code,用来访问微信提供的url地址,这是会跳转到微信的一个带二维码的页面,如下图:
用户扫码授权成功会跳转到你填写的转发地址(和公众号的授权的逻辑步骤是一样的,可以参考我前几篇写的微信开发)并且会带上一个auth_code。
url地址:https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid={0}&pre_auth_code={1}&redirect_uri={2}
method:get
params:component_appid、pre_auth_code、redirect_uri(转发的URL地址)
获取authorization_code
request.getParameter(“auth_code”)获取authorization_code,
getAuthAccessToken方法是获取authorizer_access_token
获取authorizer_access_token(可用来代公众号授权登录,获取用户的openid和用户信息等)
url:https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token={0}
method:post
type:json
params:
component_appid:第三方平台的appid
authorization_code:上步获取到的code
注意:authorizer_access_token的有效期为2小时,所以需要存在数据库中。上述接口也会返回:authorizer_refresh_token刷新token,当时间超过2个小时后,开发者需要通过刷新token来更新authorizer_access_token,以此来确保token的长持久性。so,authorizer_refresh_token也需要存在数据库中。
利用authorizer_refresh_token获取authorizer_access_token
authorizer_refresh_token需要妥善保管,当丢失后需要重新授权才能拿到。
url地址:
https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token={0}
method:post
type:json
params:
component_appid:第三方平台appid
authorizer_appid:授权方appid
authorizer_refresh_token:刷新token
二、代公众号发起网页授权,获取用户信息
当完成上述步骤后就可以代公众号发起网页授权了,获取用户openID,获取用户信息。
代公众号发起网页授权
url:https://open.weixin.qq.com/connect/oauth2/authorize
method:get
params:
appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}&component_appid={5}#wechat_redirect
获取用户openID和用户基本信息
可参考前几篇写的获取用户信息
总结:微信官方文档里至始至终都没提到authorizer_access_token和公众号的token的作用是一样的,并且两者不冲突(即在获取某一个时不会导致另一个失效)。这是微信的一个大坑(吐槽一下…)。
未完待续。。。
在申请的第三方平台下填写的开发者资料里有:授权测试公众号列表、授权事件接受的URL,首先要在测试列表里添加:公众号的原始ID,然后在URl地址里用java代码处理微信每10分钟推送过来xml啦,然后的步骤是解析xml,获取component_verify_ticket —> 调用接口获取component_access_token —>获取预授权码pre_auth_code(可存在数据库中) — >回复微信success — >引导用户进去授权页 —>获取authorization_code —>换取authorizer_access_token(它和普通公众号的基础token作用一样,也能获取用户的openId和用户信息)
第三方公众号获取微信推送的xml
/** * 微信授权事件的接受 * @return */ @RequestMapping(value="/authorize",method={RequestMethod.GET,RequestMethod.POST}) public void acceptAuthorizeEvent( HttpServletResponse response,HttpServletRequest request){ try { //处理授权事件 weChatThridService.handleAuthorize(request,response); PrintWriter pw = response.getWriter(); pw.write("success"); pw.flush(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
handleAuthorize方法用来接受处理xml:
/** * 处理微信授权事件 * @param request * @param response * @throws Exception */ public void handleAuthorize(Ht 4000 tpServletRequest request, HttpServletResponse response) throws Exception { // TODO Auto-generated method stub String timestamp=request.getParameter("timestamp"); String encrypt_type=request.getParameter("encrypt_type"); String nonce=request.getParameter("nonce"); String msg_signature=request.getParameter("msg_signature"); Log.logger.info("timestamp:"+timestamp); Log.logger.info("encrypt_type:"+encrypt_type); Log.logger.info("nonce:"+nonce); Log.logger.info("msg_signature:"+msg_signature); //验证通过后 StringBuilder sb = new StringBuilder(); BufferedReader in = request.getReader(); String line; while ((line = in.readLine()) != null) { sb.append(line); } String xml = sb.toString(); Log.logger.info("微信推送的原生:"+xml); String encodingAesKey =WeChatContants.encodingAesKey;// 第三方平台组件加密密钥 String appId=WeChatContants.THRID_APPID;//从xml中解析 WXBizMsgCrypt pc = new WXBizMsgCrypt(WeChatContants.token, encodingAesKey,appId); xml = pc.decryptMsg(msg_signature, timestamp, nonce, xml); Log.logger.info("解密后的:"+xml);
上述用到的加密解密工具类可以点击这里下载使用,这里的WeChatContants.token和encodingAesKey就是在开发者资料填写的token和key。
获取component_verify_ticket(第三方验证的票据)
解析上述解密后的xml文件,获取节点component_verify_ticket内容,后续用来调用微信接口获取第三方通行token.
接上述代码:
Map<String, String> parseXml = WeChatUtils.parseXml(xml); String component_verify_ticket=parseXml.get("ComponentVerifyTicket"); Log.logger.info(component_verify_ticket);
调用微信接口获取component_access_token
url:https://api.weixin.qq.com/cgi-bin/component/api_component_token
method:post
type:json
params:
component_appid(第三方公众号appid,第三方公众号创建好后即可知道)、
component_appsecret(第三方公众号的appsecret,同上)、
component_verify_ticket(上步获取到component_verify_ticket)
接上述代码:
/************调用接口获取component_access_token***************/ WeChatThridGetTokenVo thridGetToken=new WeChatThridGetTokenVo(); thridGetToken.setComponent_appid(WeChatContants.THRID_APPID); thridGetToken.setComponent_appsecret(WeChatContants.THRID_APPSECRET); thridGetToken.setComponent_verify_ticket(component_verify_ticket); String result = HttpNetUtils.getInstance().httpByJson(WeChatContants.THRID_COMPONENT_ACCESS_TOKEN, "POST",thridGetToken); Log.logger.info(result); if(result.contains("component_access_token")){ WeChatComponentAccessTokenVo componentAccessToken=JSON.parseObject(result,WeChatComponentAccessTokenVo.class); component_access_token=componentAccessToken.getComponent_access_token(); }else{ Log.logger.info("获取component_access_token失败!"); }
第三方公众号获取预授权码pre_auth_code
url地址:
https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token={0}
method:post
type:json
params:
component_appid:第三方平台公众号appid
解析json,并将component_access_token存在数据库中,用来授权时使用。
接上述代码:
/*****************获取预授权码pre_auth_code*************************/ Object[]object={component_access_token}; String preUrl=MessageFormat.format(WeChatContants.THRID_PRE_AUTH_CODE,object); WeChatGetPreAuthCodeVo getPreAuthCodeVo=new WeChatGetPreAuthCodeVo(); getPreAuthCodeVo.setComponent_appid(WeChatContants.THRID_APPID); String result1 = HttpNetUtils.getInstance().httpByJson(preUrl,"POST",getPreAuthCodeVo); Log.logger.info(result1); String preAuthCode=""; if(result1.contains("pre_auth_code")){ WeChatPreAuthCodeVo preAuthCodeVo= JSON.parseObject(result1,WeChatPreAuthCodeVo.class); preAuthCode=preAuthCodeVo.getPre_auth_code(); //将预授权码存在数据库中 Map<String, Object> where = new HashMap<String, Object>(); where.put("dic_type_id","THRID_WECHAT_PRE_CODE"); QueryResult<CsDictVo> page = csDictService.findByPage(where); if(page.getList()!=null&&page.getList().size()>0){ CsDictVo csDictVo = page.getList().get(0); CsDict csDict=new CsDict(); BeanCopyPropertyUtils.copyProperties(csDict,csDictVo); csDict.setDicCode(preAuthCode); csDict.setDicValue(new Date().toString()); csDictService.update(csDict); } }else{ Log.logger.info("获取pre_auth_code失败!"); } }
引导普通公众号进入授权页面进行扫码授权
从数据库中获取上步存入的预授权码:pre_auth_code,用来访问微信提供的url地址,这是会跳转到微信的一个带二维码的页面,如下图:
用户扫码授权成功会跳转到你填写的转发地址(和公众号的授权的逻辑步骤是一样的,可以参考我前几篇写的微信开发)并且会带上一个auth_code。
url地址:https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid={0}&pre_auth_code={1}&redirect_uri={2}
method:get
params:component_appid、pre_auth_code、redirect_uri(转发的URL地址)
/** * 引导用户进入授权页面 */ @RequestMapping(value="/goAuthPage",method={RequestMethod.GET,RequestMethod.POST}) public String goAuthPage( HttpServletResponse response,HttpServletRequest request){ String result="auth"; try { request.getSession(); //查找预授权码 String preAuthCode = weChatThridService.getPreAuthCode(); if(preAuthCode.equals("")){ request.setAttribute("errorMsg","预授权码为空!"); return "error"; } /**********************跳转到授权页面********************************/ Object[]object1={WeChatContants.THRID_APPID,preAuthCode,"http://自己的域名.com/a/weixin2/authInfo"}; String authorizationUrl=MessageFormat.format(WeChatContants.THRID_AUTHORIZATION_CODE,object1); Log.logger.info("跳转的URL:"+authorizationUrl); response.sendRedirect(authorizationUrl); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; }
获取authorization_code
request.getParameter(“auth_code”)获取authorization_code,
getAuthAccessToken方法是获取authorizer_access_token
/** * 处理微信授权事件完成跳转URL * @return */ @RequestMapping(value="/authInfo",method={RequestMethod.GET,RequestMethod.POST}) public String successAuthorizeInfo( HttpServletResponse response,HttpServletRequest request){ String result="error"; try { //获取authorization_code String authorization_code=request.getParameter("auth_code"); Log.logger.info("auth_code:"+authorization_code); //换取authorizer_access_token String authAccessToken = weChatThridService.getAuthAccessToken(authorization_code); if(authAccessToken.equals("configError")){ request.getSession().setAttribute("errorMsg", "缺少配置,请联系管理员!"); return "error"; }else if(authAccessToken.equals("httpError")){ request.getSession().setAttribute("errorMsg", "微信返回信息失败!"); return "error"; } }catch (Exception e) { // TODO: handle exception Log.logger.info(e.getMessage()); } request.setAttribute("errorMsg","授权成功!"); return result; }
获取authorizer_access_token(可用来代公众号授权登录,获取用户的openid和用户信息等)
url:https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token={0}
method:post
type:json
params:
component_appid:第三方平台的appid
authorization_code:上步获取到的code
注意:authorizer_access_token的有效期为2小时,所以需要存在数据库中。上述接口也会返回:authorizer_refresh_token刷新token,当时间超过2个小时后,开发者需要通过刷新token来更新authorizer_access_token,以此来确保token的长持久性。so,authorizer_refresh_token也需要存在数据库中。
/** * 通过authorization_code换取可以调用api的accessToken * @param authorization_code * @throws Exception */ public String getAuthAccessToken(String authorization_code) throws Exception { // TODO Auto-generated method stub String data=""; Log.logger.info("component_access_token为:"+component_access_token); Object[]objects={component_access_token}; String authAccessToken = MessageFormat.format(WeChatContants.THRID_AUTH_ACCESS_CODE, objects); WeChatGetAuthAccessTokenVo getAuthAccessTokenVo =new WeChatGetAuthAccessTokenVo(); getAuthAccessTokenVo.setAuthorization_code(authorization_code); getAuthAccessTokenVo.setComponent_appid(WeChatContants.THRID_APPID); String result = HttpNetUtils.getInstance().httpByJson(authAccessToken, "POST", getAuthAccessTokenVo); Log.logger.info(result); String authorizer_access_token=""; String authorizer_refresh_token=""; if(result.contains("authorization_info")){ WeChatAuthorizationInfoDataVo authInfo= JSON.parseObject(result,WeChatAuthorizationInfoDataVo.class); authorizer_access_token=authInfo.getAuthorization_info().getAuthorizer_access_token(); authorizer_refresh_token=authInfo.getAuthorization_info().getAuthorizer_refresh_token(); }else{ Log.logger.info("获取authorizer_access_token失败!"); data="httpError"; } Log.logger.info(authorizer_access_token); //将authorizer_access_token和authorizer_refresh_token存在字典表里 Map<String, Object> where = new HashMap<String, Object>(); where.put("dic_type_id","AUTHORIZER_ACCESS_TOKEN"); QueryResult<CsDictVo> page = csDictService.findByPage(where); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if(page.getList()!=null&&page.getList().size()>0){ CsDictVo csDictVo = page.getList().get(0); CsDict csDict=new CsDict(); BeanCopyPropertyUtils.copyProperties(csDict,csDictVo); csDict.setDicCode(authorizer_access_token); csDict.setDicValue(sdf.format(new Date())); csDictService.update(csDict); }else{ data="configError"; } //将refresh_token存在字典表里 Map<String, Object> where1 = new HashMap<String, Object>(); where1.put("dic_type_id","THRID_REFRESH_TOKEN"); QueryResult<CsDictVo> page1 = csDictService.findByPage(where1); if(page1.getList()!=null&&page1.getList().size()>0){ CsDictVo csDictVo = page.getList().get(0); CsDict csDict=new CsDict(); BeanCopyPropertyUtils.copyProperties(csDict,csDictVo); csDict.setDicCode(authorizer_refresh_token); csDict.setDicValue(sdf.format(new Date())); csDictService.update(csDict); }else{ data="configError"; } return data; }
利用authorizer_refresh_token获取authorizer_access_token
authorizer_refresh_token需要妥善保管,当丢失后需要重新授权才能拿到。
url地址:
https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token={0}
method:post
type:json
params:
component_appid:第三方平台appid
authorizer_appid:授权方appid
authorizer_refresh_token:刷新token
//调用微信接口重新获取access_token Object[]objects={component_access_token}; String refreshUrl=MessageFormat.format(WeChatContants.THRID_REFRESH_TOKEN, objects); WeChatGetRefreshTokenVo refreshTokenVo=new WeChatGetRefreshTokenVo(); refreshTokenVo.setAuthorizer_appid(wechatConfig.getWxappid()); refreshTokenVo.setAuthorizer_refresh_token(csDictVo.getDicCode()); refreshTokenVo.setComponent_appid(WeChatContants.THRID_APPID); Log.logger.info(refreshUrl); String httpByJson = HttpNetUtils.getInstance().httpByJson(refreshUrl,"POST",refreshTokenVo); Log.logger.info(httpByJson); if(httpByJson.contains("authorizer_access_token")){ WeChatAuthorizerAccessTokenVo authorizerAccessTokenVo = JSON.parseObject(httpByJson, WeChatAuthorizerAccessTokenVo.class); thridToken = authorizerAccessTokenVo.getAuthorizer_access_token(); //并将它存在数据字典里面 Map<String, Object> where1 = new HashMap<String, Object>(); where1.put("dic_type_id","AUTHORIZER_ACCESS_TOKEN"); QueryResult<CsDictVo> page1 = csDictService.findByPage(where1); CsDictVo csDictVo2 = page1.getList().get(0); CsDict csDict=new CsDict(); BeanCopyPropertyUtils.copyProperties(csDict,csDictVo2); csDict.setDicCode(thridToken); csDict.setDicValue(DateFromtUtils.getDataFormatYMDHMS24(new Date())); csDictService.update(csDict); }else{ thridToken="httpError"; }
二、代公众号发起网页授权,获取用户信息
当完成上述步骤后就可以代公众号发起网页授权了,获取用户openID,获取用户信息。
代公众号发起网页授权
url:https://open.weixin.qq.com/connect/oauth2/authorize
method:get
params:
appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}&component_appid={5}#wechat_redirect
//转发地址 String redUrl=URLEncoder.encode("http://自己的域名.com/b/weixin2/hongbao", "UTF-8"); String params=WeChatContants.THRID_WECHAT_OAUTH_PARAMS; Object[]array={wechatConfig.getWxappid(),redUrl,"code","snsapi_base",1,WeChatContants.THRID_APPID}; String formatparams = MessageFormat.format(params, array); Log.logger.info(WeChatContants.THRID_WECHAT_OAUTH_URL+"?"+formatparams); //将转发地址存在session中,方便code失效时重新连接 request.getSession().setAttribute("oauthLink",WeChatContants.THRID_WECHAT_OAUTH_URL+"?"+formatparams); //微信授权转发 response.sendRedirect(WeChatContants.THRID_WECHAT_OAUTH_URL+"?"+formatparams);
获取用户openID和用户基本信息
可参考前几篇写的获取用户信息
总结:微信官方文档里至始至终都没提到authorizer_access_token和公众号的token的作用是一样的,并且两者不冲突(即在获取某一个时不会导致另一个失效)。这是微信的一个大坑(吐槽一下…)。
未完待续。。。
相关文章推荐
- java开发微信第三方平台 模板消息发送消息案例
- 微信开发(4):微信第三方开放平台的搭建(java)
- 微信第三方平台开发中遇到的问题总结---java
- Android平台第三方应用分享到微信开发
- 微信公共平台接口开发--Java实现
- 微信开放平台 公众号第三方平台开发 教程二 创建公众号第三方平台
- 微信开放平台 公众号第三方平台开发 教程五 代公众号发起网页授权源码
- 微信开放平台 公众号第三方平台开发 教程二 创建公众号第三方平台
- Android平台第三方应用分享到微信开发
- Android平台第三方应用分享到微信开发
- 微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台
- 微信第三方平台开发——整体框架示意图
- 微信开放平台 公众号第三方平台开发 教程五 代公众号发起网页授权源码
- 微信公众开放平台开发03---百度BAE上搭建属于自己的微信公众平台 -JAVA,微信公众开放平台部署到百度云中BASE2.0,进行调试,木有钱买云服务器的亲们试试
- 微信开放平台 公众号第三方平台开发 教程四 代公众号调用接口的SDK和demo
- 【COCOS2DX-ANDROID-游戏开发之十二】Android平台第三方应用分享到微信开发
- [转载]Android平台第三方应用分享到微信开发
- 微信公众开放平台开发08---纯java 实现微信开发:编写自定义菜单
- OpenSSL爆出本年度最严重的安全漏洞heartbleed,微信第三方开发平台应第一时间升级OpenSSL
- 微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台