接入微信公众平台之验证服务器地址的有效性

根据官网文档的介绍,接入微信公众平台有三步:

  接入微信公众平台开发,开发者需要按照如下步骤完成:

  1、填写服务器配置

  2、验证服务器地址的有效性

  3、依据接口文档实现业务逻辑

本文主要记录第二步,即验证服务器地址的有效性(验证消息的确来自微信服务器)

  开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

 

参数 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

  

  开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:

1)将token、timestamp、nonce三个参数进行字典序排序

2)将三个参数字符串拼接成一个字符串进行sha1加密

3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

代码部分:

  1)、字典排序方法:

/**
     * 排序方法
     * @param token
     * @param timestamp
     * @param nonce
     * @return
     */
    public String sort(String token, String timestamp, String nonce) {
        String[] strArray = {token, timestamp, nonce};
        Arrays.sort(strArray);
        StringBuilder sb = new StringBuilder();
        for (String str : strArray) {
            sb.append(str);
        }

        return sb.toString();
    }

  2)、sha1加密:

/**
     * 加密的方法
     * @param str  要加密的字符串
     * @return 加密后的内容
     */
    public String sha1(String str)  {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

  3)、调用排序和加密,比较

public void checkVerification(HttpServletRequest request, HttpServletResponse response) {
        logger.info("开始校验签名...");
        /**
         * 接收微信服务器发送请求时传递过来的4个参数
         */
        String signature = request.getParameter("signature");//微信加密签名signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
        String timestamp = request.getParameter("timestamp");//时间戳
        String nonce = request.getParameter("nonce");//随机数
        String echostr = request.getParameter("echostr");//随机字符串

        System.out.println(timestamp+"---------"+nonce);
        //排序
        String sortString = sort(TOKEN, timestamp, nonce);

        //加密
        String mySignature = sha1(sortString);

        //校验签名
        if (mySignature != null && mySignature != "" && mySignature.equals(signature)) {
            logger.info("签名校验通过。");
            //如果检验成功输出echostr,微信服务器接收到此输出,才会确认检验完成。
            //response.getWriter().println(echostr);
            try {
                response.getWriter().write(echostr);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            logger.info("签名校验失败。");
        }

    }

  

posted @ 2017-06-28 10:51  敲代码的小松鼠  阅读(1659)  评论(0编辑  收藏  举报

你若不想做,总会找到“接口”;你若想做,总会找到“方法”。