JAVA微信开放平台授权
2016-03-25 09:51
447 查看
刚开发完微信授权接入,这里做个分享,供大家参考。
授权流程可以参照微信官方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
/**
* 提取出xml数据包中的加密消息
*
* @param xmltext 待提取的xml字符串
* @param element xml中参数名称 可选 "ToUserName","AppId"(自己创建的枚举AnotherElement,有ToUserName和AppId俩个成员)
* @return 提取出的加密消息字符串
* @throws AesException
*/
public static Object[] extract(String xmltext, WXBizMsgCrypt.AnotherElement element) throws AesException {
Object[] result = new Object[3];
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(xmltext);
InputSource is = new InputSource(sr);
Document document = db.parse(is);
Element root = document.getDocumentElement();
NodeList nodelist1 = root.getElementsByTagName("Encrypt");
NodeList nodelist2 = root.getElementsByTagName(element.name());
result[0] = 0;
result[1] = nodelist1.item(0).getTextContent();
result[2] = nodelist2.item(0).getTextContent();
return result;
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.ParseXmlError);
}
}
2.流程图代码解释
①⑨授权事件URL接收到微信的请求,包括ticket推送和授权消息通知:
[java] view
plain copy
@Override
public void handleWechatEventPush (HttpServletRequest request){
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String msgSignature = request.getParameter("msg_signature");
StringWriter writer = new StringWriter();
try {
//获得微信发来的加密消息
IOUtils.copy(request.getInputStream(), writer, "UTF-8");
String fromXML = writer.toString();
WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, encodingAESKey, componentAppId);
//获得解密后的XML消息体
String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML, WXBizMsgCrypt.AnotherElement.AppId);
LOGGER.info(" authorize decrypt result {}", result);
Map<String, String> map = MessageUtil.parseXml(result);
//消息类型
String infoType = map.get("InfoType");
switch (InfoType.valueOf(infoType)) {
//授权成功,可以获得授权码;授权码也可以在流程图⑤中获得,所以可以忽略
case authorized:
break;
//取消授权,可以删除本地保存的已授权公众号
case unauthorized:
String appId = map.get("AuthorizerAppid");
//todo 删除本地授权的公众号
break;
//更新授权,可以更新授权方令牌authorizer_access_token,刷新令牌authorizer_refresh_token,权限集列表等
case updateauthorized:
//todo 更新令牌等
break;
//推送ticket,妥善保存ticket,用于获取component_access_token
case component_verify_ticket:
String ticket = map.get("ComponentVerifyTicket");
//存储ticket
break;
default:
break;
}
} catch (Exception e) {
LOGGER.error(e.toString(), e);
}
}
⑤点击链接后进入授权页如下(切记要配置测试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
@Override
public String thirdPlatformPrecessRequest(HttpServletRequest request, String appId) {
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String msgSignature = request.getParameter("msg_signature");
StringWriter writer = new StringWriter();
try {
IOUtils.copy(request.getInputStream(), writer, "UTF-8");
String fromXML = writer.toString();
WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, encodingAESKey, componentAppId);
String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML, WXBizMsgCrypt.AnotherElement.ToUserName);//这里传入的是ToUserName,参见上面的准备工作
Map<String, String> resultMap = MessageUtil.parseXml(result);
String respMessage = getRespMessage(resultMap);
return pc.encryptMsg(respMessage, timestamp, nonce);
} catch (Exception e) {
LOGGER.error(e.toString(), e);
return "";
}
}
授权流程可以参照微信官方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
/**
* 提取出xml数据包中的加密消息
*
* @param xmltext 待提取的xml字符串
* @param element xml中参数名称 可选 "ToUserName","AppId"(自己创建的枚举AnotherElement,有ToUserName和AppId俩个成员)
* @return 提取出的加密消息字符串
* @throws AesException
*/
public static Object[] extract(String xmltext, WXBizMsgCrypt.AnotherElement element) throws AesException {
Object[] result = new Object[3];
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(xmltext);
InputSource is = new InputSource(sr);
Document document = db.parse(is);
Element root = document.getDocumentElement();
NodeList nodelist1 = root.getElementsByTagName("Encrypt");
NodeList nodelist2 = root.getElementsByTagName(element.name());
result[0] = 0;
result[1] = nodelist1.item(0).getTextContent();
result[2] = nodelist2.item(0).getTextContent();
return result;
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.ParseXmlError);
}
}
2.流程图代码解释
①⑨授权事件URL接收到微信的请求,包括ticket推送和授权消息通知:
[java] view
plain copy
@Override
public void handleWechatEventPush (HttpServletRequest request){
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String msgSignature = request.getParameter("msg_signature");
StringWriter writer = new StringWriter();
try {
//获得微信发来的加密消息
IOUtils.copy(request.getInputStream(), writer, "UTF-8");
String fromXML = writer.toString();
WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, encodingAESKey, componentAppId);
//获得解密后的XML消息体
String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML, WXBizMsgCrypt.AnotherElement.AppId);
LOGGER.info(" authorize decrypt result {}", result);
Map<String, String> map = MessageUtil.parseXml(result);
//消息类型
String infoType = map.get("InfoType");
switch (InfoType.valueOf(infoType)) {
//授权成功,可以获得授权码;授权码也可以在流程图⑤中获得,所以可以忽略
case authorized:
break;
//取消授权,可以删除本地保存的已授权公众号
case unauthorized:
String appId = map.get("AuthorizerAppid");
//todo 删除本地授权的公众号
break;
//更新授权,可以更新授权方令牌authorizer_access_token,刷新令牌authorizer_refresh_token,权限集列表等
case updateauthorized:
//todo 更新令牌等
break;
//推送ticket,妥善保存ticket,用于获取component_access_token
case component_verify_ticket:
String ticket = map.get("ComponentVerifyTicket");
//存储ticket
break;
default:
break;
}
} catch (Exception e) {
LOGGER.error(e.toString(), e);
}
}
⑤点击链接后进入授权页如下(切记要配置测试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
@Override
public String thirdPlatformPrecessRequest(HttpServletRequest request, String appId) {
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String msgSignature = request.getParameter("msg_signature");
StringWriter writer = new StringWriter();
try {
IOUtils.copy(request.getInputStream(), writer, "UTF-8");
String fromXML = writer.toString();
WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, encodingAESKey, componentAppId);
String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML, WXBizMsgCrypt.AnotherElement.ToUserName);//这里传入的是ToUserName,参见上面的准备工作
Map<String, String> resultMap = MessageUtil.parseXml(result);
String respMessage = getRespMessage(resultMap);
return pc.encryptMsg(respMessage, timestamp, nonce);
} catch (Exception e) {
LOGGER.error(e.toString(), e);
return "";
}
}
相关文章推荐
- 微信公众平台开发 OAuth2.0网页授权
- 一步一步实现iOS微信自动抢红包(非越狱)
- hadoop集群运行小程序wordCount记录
- PHP 生成微信红包代码简单
- Android ActionBar应用实战,高仿微信主界面的设计
- 仿微信语音功能的流程
- 微信蓝牙BLE接入调试指引 硬件篇
- 微信H5 长按二维码识别不了
- 微信中打开网页,链接无法跳转处理
- 微信公众号(服务号)接入开发(2)之微信授权登陆
- 微信分享 JavaScript 代码 2016
- Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等
- 小程序 - 翻转字符串
- 使用Chrome修改user agent模拟微信内置浏览器
- GPS坐标转百度地图并且加载地图示例.支持微信端访问
- Android AccessibilityService实现微信自动抢红包
- 微信多客服插件获取openid
- 一步一步实现iOS微信自动抢红包(非越狱)
- .NET微信公众号开发之创建自定义菜单
- 微信支付遇到的坑