微信公众号开发java系列(一)

      最近一段时间接触了微信公众号和小程序的Java开发。这两类的开发在目前市场上已经是比较常见,得益于微信庞大的用户基数,这两类的项目在这两年也开始迅速崛起,尤其是小程序这一块,增长更是迅猛。自己打算把开发过程中的一些经历记录下来,相信不管对于初学者还是自己以后进行回顾都是能够带来帮助的,希望自己能够把这块坚持下去。

     现在进入正题,第一篇简单一点,从比较传统的微信公众号开发入手。这一篇代码内容不会很多,先当热身。第一步我们需要登录微信公众开放平台(微信公众号和小程序的文档开发都可以在这里找到),当然,你需要有一个微信公众号的账号。

    进入之后,左边一列导航找到开发-基本配置      

微信公众号配置服务器页面java 微信公众号 服务器配置_java

点击之后你就可以看到这样的界面

微信公众号配置服务器页面java 微信公众号 服务器配置_java_02

点击服务器配置中的修改配置,进去之后可以看到

微信公众号配置服务器页面java 微信公众号 服务器配置_java_03

对于服务器配置来说,我们需要设置url和token,aeskey和消息验证有关,下面的的消息加解密方式可以自由选择,开发的时候可以选择兼容。我们在微信公众号中申请一个测试账号。进入之后可以看到

微信公众号配置服务器页面java 微信公众号 服务器配置_微信_04

测试账号会提供给开发者appid和appsecret,token可以自己自定义一个加密字符串32位以内就可以了。这里的url可以使用域名。本地调试的话就使用ngrok做一个内网穿透就可以了。url指向接受微信服务器消息的接口地址。

微信官方给出的是将token、timestamp、nonce三个参数进行字典序排序 2)将三个参数字符串拼接成一个字符串进行sha1加密 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。

/**
     * @param request
     * @return
     * @description 验证微信的token
     * @author zhou
     * @date 2019/6/1
     */
    @GetMapping("/tokenVerification")
    public void tokenVerification(HttpServletRequest request,
                                  HttpServletResponse response) {
        //微信加密签名
        String signature = request.getParameter("signature");
        //时间戳
        String timestamp = request.getParameter("timestamp");
        //随机数
        String nonce = request.getParameter("nonce");
        //随机字符串
        String echostr = request.getParameter("echostr");
        try {
            //获取sha1加密
            String sha1Result = SHA1.getSHA1(wxOfficialsAccountConfiguration.getToken(),
                    timestamp, nonce);
            //判断和签名是否一致
            if (sha1Result.equals(signature)) {
                response.getWriter().write(echostr);
            }else{
                throw new WeChatOaException(WeChatOaErrorEnum.NOT_FROM_WECHAT);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

根据文档微信将会发送加密签名signature、时间戳timestamp、随机数nonce、随机字符串echostr。echostr是最后验证通过要返回给微信服务器的,我们先放一边。按照步骤对另外三个时间戳,随机数,和我们配置的token参数进行加密,

(1)进行字典排序

(2)将数组拼接成String,进行sha1加密

(3)和微信发来的signature作比较,判断是否相等

注意,微信公众号配置的token和这里进行加密的token必须一致。因为这个signature就是用配置的token得到的。

如果相等就将之前的随机字符串echostr返回

/**
     * 用SHA1算法生成安全签名
     * @param token 票据
     * @param timestamp 时间戳
     * @param nonce 随机字符串
     * @return 安全签名
     * @throws AesException
     */
    public static 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(AesErrorEnum.COMPUTE_SIGNATURE_ERROR);
        }
    }

至此,微信服务器配置就结束了。