说道握手,意思就是相互交流和确认通讯方式。那么要实现与微信服务器交流协作,就必须与微信服务器进行握手,确定好交流的方式。
在官方开发文档上写明了二次开发的步骤
请仔细研读
http://mp.weixin.qq.com/wiki/17/2d4265491f12608cd170a95559800f2d.html
相信看完了这个文档,应该对二次开发流程有所了解。
进入主题:如何实现与微信握手
(走到这里,默认你拥有了对外开放80端口的服务器,已经认证的微信号<测试号也可以>,如果没达到要求请自行解决)
首先,微信服务器验证开发服务器有效的方法就是向开发服务器发送一个Get请求,如果这个请求有效并返回了指定的文本即验证通过,否则验证失败。
那么这个Get请求是如何构成?它是由4个参数构成.
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串
在此假设80端口服务器地址为 http://wx.xxx.com/meeting,那么可以清楚的知道微信服务器发送的Get请求如下:
那么在开发服务器就要设计一个Get方法接收4个参数
@ResponseBody
@RequestMapping(value="/meeting",method = RequestMethod.GET)
public String Meeting(@RequestParam String signature,
@RequestParam String timestamp,
@RequestParam String nonce,
@RequestParam String echostr){
/*验证是否是微信服务器*/
}
如何验证微信服务器传过来的参数呢?
官方文档要求对传过来的参数进行排序并进行SHA1编码,考虑到这个是验证方法,所以可以写成通用方法如下
public static String isWxService(String signature,String timestamp,String nonce,String echostr){
List<String> params = new ArrayList<String>();
//此处获取公众号的Token
params.add(wxConfig.getTOKEN());
params.add(timestamp);
params.add(nonce);
//1. 将token、timestamp、nonce三个参数进行字典序排序
Collections.sort(params, new Comparator<String>() {
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
//2. 将三个参数字符串拼接成一个字符串进行sha1加密
String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));
if (temp.equals(signature)) {
return echostr;
}
return "";
}
/**
* Takes the raw bytes from the digest and formats them correct.
*
* @param bytes the raw bytes from the digest.
* @return the formatted bytes.
*/
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
public static String encode(String str) {
if (str == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.update(str.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
上面代码包含了排序与SHA1加密,仅仅实现微信服务器验证代码如下
@ResponseBody
@RequestMapping(value="/meeting",method = RequestMethod.GET)
public String Meeting(@RequestParam String signature,
@RequestParam String timestamp,
@RequestParam String nonce,
@RequestParam String echostr){
/*验证是否是微信服务器*/
return isWxService(signature,timestamp,nonce,echostr);
}
至此就完成了微信服务器验证