阅读本文前,请先认真阅读微信官方文档:微信公众号技术文档之接入指南
接入概述
接入微信公众平台开发,开发者需要按照如下步骤完成:
1、填写服务器配置
2、验证服务器地址的有效性
3、依据接口文档实现业务逻辑
本文主要介绍第二个步骤的代码实现。
第二步:验证消息的确来自微信服务器
-
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上
(由于消息加解密方式选择的为明文模式,需加密模式时从官方文档下载Java部分代码,去除注释部分代码即可)/** * 消息加解密接入 */ public class EntryController extends Controller { public void accept() throws IOException { String method = getRequest().getMethod(); if ("GET".equals(method)) { doGet();//开发者模式验证 }else { doPost();//接收消息 } } /* * 响应get请求,微信默认token校验时使用get请求 */ private void doGet(){ //接收微信用来校验信息的内置规定参数 String msgSignature =getPara("signature"); // 微信加密签名 String timeStamp = getPara("timestamp"); // 时间戳 String nonce = getPara("nonce"); // 随机数 String echoStr = getPara("echostr"); // 随机字符串 //// 创建加密类 //WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WechartConst.Token, WechartConst.EncodingAESKey,WechartConst.appId); // // 比对msgSignature 用token, timeStamp, nonce加密的参数是否一致,一致证明该接口来自微信,异常则不是来自微信 //String echostr = wxcpt.verifyUrl(msgSignature, timeStamp, nonce, echoStr); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 //获取微信服务器中配置的Token的值 String token = SystemConfig.WECHAT_TOKEN; if (WechatUtil.checkSignature(msgSignature,token, timeStamp, nonce)){ //原样返回echostr参数内容 renderJson(echoStr); } } }
-
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信public class WechatUtil { /** * 验证消息的确来自微信服务器 * @param msgSignature 微信加密签名 * @param token 开发者填写的token参数 * @param timeStamp 时间戳 * @param nonce 随机数 * @return * @throws */ public static boolean checkSignature(String msgSignature, String token,String timeStamp, String nonce) { // 1.将token、timestamp、nonce三个参数进行字典序排序 String[] arr = new String[]{token, timeStamp, nonce}; Arrays.sort(arr); // 2. 将三个参数字符串拼接成一个字符串进行sha1加密 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 = BytesParserUtil.byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // 3.将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(msgSignature.toUpperCase()) : false; } }
注:代码中使用到的工具类请参考: 字节转换工具---- BytesParserUtil