微信公众号服务器接入只需要验证TOKEN的正确性
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
1.将token、timestamp、nonce三个参数进行字典序排序
2.将三个参数字符串拼接成一个字符串进行sha1加密
3.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
Java代码示例如下
@RequestMapping("/checkToken")@ResponseBodypublic Object checkToken(HttpServletRequest request) throws Exception{logger.info("CheckTokenController checkToken start");String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");String signature = request.getParameter("signature");String echoStr = request.getParameter("echostr");logger.info("CheckTokenController checkToken param:{}",String.format("timestamp:%s,nonce:%s,signature:%s,echoStr:%s",timestamp,nonce,signature,echoStr));String tmpArr = getSHA1(token,timestamp,nonce);if(tmpArr.equals(signature)){return echoStr;}else {throw new AesException(puteSignatureError);}}public String getSHA1(String token, String timestamp, String nonce) throws AesException{try {String[] array = new String[] { token, timestamp, nonce};StringBuffer sb = new StringBuffer();// 字符串排序Arrays.sort(array);for (int i = 0; i < 3; i++) {sb.append(array[i]);}String str = sb.toString();// SHA1签名生成MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(str.getBytes());byte[] digest = md.digest();StringBuffer hexstr = new StringBuffer();String shaHex = "";for (int i = 0; i < digest.length; i++) {shaHex = Integer.toHexString(digest[i] & 0xFF);if (shaHex.length() < 2) {hexstr.append(0);}hexstr.append(shaHex);}return hexstr.toString();} catch (Exception e) {e.printStackTrace();throw new AesException(puteSignatureError);}}
此处有几个需要注意的点
1.关于报错java.security.InvalidKeyException:illegal Key Size
需要在/technetwork/java/javase/downloads/jce-7-download-432124.html下载这个压缩包,解压后能看到两个文件local_policy.jar和US_export_policy.jar
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件
如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件
2.针对mons.codec.binary.Base64,需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
官方下载地址:/proper/commons-codec/download_codec.cgi
3.理论上来说,不进行验证,直接返回echoStr,也可以完成服务器配置,但是这种属于非常愚蠢的做法,可能会产生一些预料之外的结果,代码如下
@RequestMapping("/checkToken")@ResponseBodypublic Object checkToken(HttpServletRequest request) throws Exception{logger.info("CheckTokenController checkToken start");String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");String signature = request.getParameter("signature");String echoStr = request.getParameter("echostr");return echoStr;}
这是因为验证服务器配置时,echoStr这个字段实际是用明文传输的,所以不解密直接返回也能配置成功
微信公众号的服务器配置成功后,即可进行下一步的开发工作