JAVA微信开放平台授权

刚开发完微信授权接入,这里做个分享,供大家参考。


授权流程可以参照微信官方api,流程图如下:



1.准备工作

导入微信官方的加解密算法(下载地址),之后要做:

 (1)   在java官方网站下载JCE无限制权限策略文件(JDK7的下载地址: * http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html)
  下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件。
如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。


(2)  修改解密算法。由于微信发来的XML消息体中可能包含ToUserName或AppId,而微信提供的解密算法中的XML节点只有ToUserName一种形式。所以需要修改XMLParse类中的extract方法:

[java]  view plain  copy
  1.  /** 
  2.      * 提取出xml数据包中的加密消息 
  3.      * 
  4.      * @param xmltext 待提取的xml字符串 
  5.      * @param element xml中参数名称 可选 "ToUserName","AppId"(自己创建的枚举AnotherElement,有ToUserName和AppId俩个成员) 
  6.      * @return 提取出的加密消息字符串 
  7.      * @throws AesException 
  8.      */  
  9.     public static Object[] extract(String xmltext, WXBizMsgCrypt.AnotherElement element) throws AesException {  
  10.         Object[] result = new Object[3];  
  11.         try {  
  12.             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
  13.             DocumentBuilder db = dbf.newDocumentBuilder();  
  14.             StringReader sr = new StringReader(xmltext);  
  15.             InputSource is = new InputSource(sr);  
  16.             Document document = db.parse(is);  
  17.   
  18.             Element root = document.getDocumentElement();  
  19.             NodeList nodelist1 = root.getElementsByTagName("Encrypt");  
  20.             NodeList nodelist2 = root.getElementsByTagName(element.name());  
  21.             result[0] = 0;  
  22.             result[1] = nodelist1.item(0).getTextContent();  
  23.             result[2] = nodelist2.item(0).getTextContent();  
  24.             return result;  
  25.         } catch (Exception e) {  
  26.             e.printStackTrace();  
  27.             throw new AesException(AesException.ParseXmlError);  
  28.         }  
  29.     }



2.流程图代码解释

①⑨授权事件URL接收到微信的请求,包括ticket推送和授权消息通知:

[java]  view plain  copy
  1. @Override  
  2.         public void handleWechatEventPush (HttpServletRequest request){  
  3.             String timestamp = request.getParameter("timestamp");  
  4.             String nonce = request.getParameter("nonce");  
  5.             String msgSignature = request.getParameter("msg_signature");  
  6.             StringWriter writer = new StringWriter();  
  7.             try {  
  8.                 //获得微信发来的加密消息  
  9.                 IOUtils.copy(request.getInputStream(), writer, "UTF-8");  
  10.                 String fromXML = writer.toString();  
  11.                 WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, encodingAESKey, componentAppId);  
  12.                 //获得解密后的XML消息体  
  13.                 String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML, WXBizMsgCrypt.AnotherElement.AppId);  
  14.                 LOGGER.info(" authorize decrypt result {}", result);  
  15.                 Map<String, String> map = MessageUtil.parseXml(result);  
  16.                 //消息类型  
  17.                 String infoType = map.get("InfoType");  
  18.                 switch (InfoType.valueOf(infoType)) {  
  19.                     //授权成功,可以获得授权码;授权码也可以在流程图⑤中获得,所以可以忽略  
  20.                     case authorized:  
  21.                         break;  
  22.                     //取消授权,可以删除本地保存的已授权公众号  
  23.                     case unauthorized:  
  24.                         String appId = map.get("AuthorizerAppid");  
  25.                        //todo 删除本地授权的公众号  
  26.                         break;  
  27.                     //更新授权,可以更新授权方令牌authorizer_access_token,刷新令牌authorizer_refresh_token,权限集列表等  
  28.                     case updateauthorized:  
  29.                     //todo 更新令牌等  
  30.                         break;  
  31.                     //推送ticket,妥善保存ticket,用于获取component_access_token  
  32.                     case component_verify_ticket:  
  33.                         String ticket = map.get("ComponentVerifyTicket");  
  34.                        //存储ticket  
  35.                         break;  
  36.                     default:  
  37.                         break;  
  38.                 }  
  39.             } catch (Exception e) {  
  40.                 LOGGER.error(e.toString(), e);  
  41.             }  
  42.         }


⑤点击链接后进入授权页如下(切记要配置测试ip地址和保证pre_auth_code有效):完成授权后,会进入redirect_url,可以从url中获取authorization_code和过期时间



     ⑥⑦⑧获得authorizer_access_token和authorizer_refresh_token。authorizer_access_token和开发微信公众平台的access_token功能一致,可以调用菜单设置等接口;另外还可以获得公众号的基本信息和其他选项设置。


3.代公众号实现消息处理

      授权成功后,微信会将消息和事件通知发送到公众号消息与事件接收URL上,与公众号开发者模式不同的是,第三方处理消息和事件通知,需要对数据进行加解密。代码如下:

[java]  view plain  copy
  1. @Override  
  2.   public String thirdPlatformPrecessRequest(HttpServletRequest request, String appId) {  
  3.   
  4.       String timestamp = request.getParameter("timestamp");  
  5.       String nonce = request.getParameter("nonce");  
  6.       String msgSignature = request.getParameter("msg_signature");  
  7.       StringWriter writer = new StringWriter();  
  8.       try {  
  9.           IOUtils.copy(request.getInputStream(), writer, "UTF-8");  
  10.           String fromXML = writer.toString();  
  11.           WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, encodingAESKey, componentAppId);  
  12.           String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML, WXBizMsgCrypt.AnotherElement.ToUserName);//这里传入的是ToUserName,参见上面的准备工作  
  13.           Map<String, String> resultMap = MessageUtil.parseXml(result);  
  14.           String respMessage = getRespMessage(resultMap);  
  15.           return pc.encryptMsg(respMessage, timestamp, nonce);  
  16.       } catch (Exception e) {  
  17.           LOGGER.error(e.toString(), e);  
  18.           return "";  
  19.       }  
  20.   }  
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值