版权声明:本文为博主汪子熙原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1439854
微信公众号开发的官方文档:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319
其中我们开发好的服务器,在配置到微信公众号开发平台的"服务器地址"之后(下图),在真正生效之前,需要通过验证。
验证逻辑:
微信服务器会发送一个HTTP GET请求到我们填写的服务器地址URL上。
这个HTTP GET请求携带的参数:
开发者需要通过编程,若确认此次GET请求是否来自微信服务器。确认的逻辑就是把token, 请求中的timestamp和nouce三个参数作为输入,按照微信公众号开发平台规定的逻辑再计算一次,结果同
如果确实是,需要原样返回echostr参数内容,这样我们开发的微信消息服务器就接入成功了。
不幸的是微信官网上提供的示例代码只有PHP版本的,
所以我这里提供一份Java版本的:
@GetMapping("/message")
@ResponseBody
public String checkToken(@RequestParam String signature, @RequestParam String timestamp,
@RequestParam String nonce, @RequestParam String echostr) {
boolean result = wxService.checkSignature(signature, timestamp, nonce, echostr);
if (result)
return echostr;
return "FAILURE";
}
checkSignature方法的实现:
public boolean checkSignature(String signature, String timestamp, String nonce, String echostr) {
String[] array = new String[]{ "这里可以硬编码一个token", timestamp, nonce};
//先对这三个字符串字典排序,然后拼接
Arrays.sort(array);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {
sb.append(array[i]);
}
//使用SHA-1算法对拼接字符串加密
MessageDigest messageDigest = null;
String hexStr = null;
try {
messageDigest = MessageDigest.getInstance("SHA-1");
byte[] digest = messageDigest.digest(sb.toString().getBytes());
//将加密后的字符串转换成16进制字符串
hexStr = StringUtil.bytesToHexStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//返回校验结果
return signature.equalsIgnoreCase(hexStr);
}
bytesToHexStr函数的实现:
/**
* @param bytes 加密字节数组
* @return 转换后的16进制字符串
* @description 字节数组转换成16进制字符串
*/
public static String bytesToHexStr(byte[] bytes) {
StringBuilder sb = new StringBuilder();
int len = bytes.length;
for (int i = 0; i < len; i++) {
String hexStr = Integer.toHexString(bytes[i] & 0xff);
if (hexStr.length() < 2) {
sb.append(0);
}
sb.append(hexStr);
}
return sb.toString();
}