微信公众号开发
目标
开发h5系统一套,前期目标是可获取微信用户信息,后期目标是达到系统通过公众号向用户推送系统消息。
搭建微信开发环境
1、可先申请微信公众平台接口测试帐号,http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login;
2、h5系统写一个微信校验接口,微信会调用此接口校验服务器有效性 。
保证本地开发的h5系统可通过公网域名访问,网络这块注意两个事项:
1)本地开发环境需要做内网IP到公网IP映射,建议同时做好IP白名单和到期时间策略,如:
访问白名单 公网地址 公网端口 内网地址 内网端口 策略到期时间
115.236.57.28 122.224.125.150 14004 192.168.25.100 8080 2016/01/31
2)微信接入文档最后一句话指明了微信公众号接口只支持80接口,所以域名端口映射可以通过代理接入。
以上网络环境搭建,公司项目建议寻求IT协助,个人项目也可到网上找一些免费的代理,推荐ngrok,ngrok国外网络不太稳定,国内也有不少这块的资源。
- 公司项目开发可能有依赖公司测试环境或者预发布环境,手机测试时会需要手机绑定hosts,网上都说手机越狱获取root权限才能修改手机hosts,其实不需要这么麻烦,使用一个手机网络的代理就行了,推荐使用Fiddler。我们可以在手机端设置http代理为Fiddler的代理服务器,使得手机应用的请求都通过Fiddler来转发,从而实现查看手机端页面请求的功能,fiddler所在的电脑绑定hosts切换测试环境或者预发布环境就行了。
接下来就可以进入开发调用微信接口了。一微信校验服务有效性;二网页微信信息授权;三微信分享好友朋友圈等。
微信校验服务有效性,参考官网API即可。http://mp.weixin.qq.com/wiki/8/f9a0b8382e0b77d87b3bcc1ce6fbc104.html
/**
* 加密/校验流程如下: 1. 将token、timestamp、nonce三个参数进行字典序排序 2.
* 将三个参数字符串拼接成一个字符串进行sha1加密 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
*
* @param request
* @throws IOException
*/
@RequestMapping("check")
public @ResponseBody void checkWxSignature(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// 微信加密签名
String signature= request.getParameter("signature");
// 时间戳
String timestamp= request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr");
PrintWriter out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
}
out.close();
out = null;
}
/**
* 验证签名
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
网页授权获取用户基本信息
首先配置一个授权回调页面域名。用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。沙盒号回调地址支持域名和ip,正式公众号回调地址只支持域名。像这种错误:redirect_uri 参数错误,就需要检查回调域名对不对了。
public static String oauth2_url ="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
/**
* 获取请求用户信息的access_token
*
* @param code
* @return
*/
public static Map<String, String> getUserInfoAccessToken(String code) {
Map<String, String> data = new HashMap<String, String>();
try {
String url = oauth2_url.replace("APPID", appid).replace("APPSECRET", appsecret).replace("CODE", code);
log.info("获取请求用户信息的access_token: {}", url);
net.sf.json.JSONObject result = WeixinUtil.httpRequest(url, "GET", null);
log.info("结果. [result={}]", result.toString());
data.put("openid", result.get("openid").toString().replaceAll("\"", ""));
data.put("access_token", result.get("access_token").toString().replaceAll("\"", ""));
} catch (Exception ex) {
log.error("获取请求用户信息的access_token异常: {}", ex);
throw new RuntimeException("获取请求用户信息的access_token异常: {}", ex);
}
return data;
}
微信分享接口
微信分享有个坑,不能在网页上自定义分享触发的dom,只能通过微信右上角分享操作。所谓的分享接口,只能是自定义分享出去呈现的内容。
其它参考接口文档开发流程即可。