您现在的位置:首页 > 资讯中心 > 网站建设知识 >

微信公众号开发之公众号服务器认证

发表于:2019-09-12 阅读:7371 关键词:

  很多企业做网络营销推广时,微信公众号是必备选项,但是自己又不懂技术,公司也没有相应人才,招一个的话又太浪费。接下来深圳网站开发公司万狼科技的小编就和大家讲一下微信公众号开发是怎么开发的,今天要说的是公众号服务器认证。

  首先,需要准备如下:

  1、公众号(个人练习的话可以用微信测试平台,下面有链接)

  2、云主机。用来做公众号服务器


  公众号

  微信公众号分为订阅号和服务号,又分别分为认证和非认证。拥有的接口权限如下图:


公众号权限


  总体来说权限规律为服务号>订阅号,认证的 >非认证的。个人非认证订阅号是最容易申请的,认证的话需要提交公司的认证。服务号申请更复杂一些。如果只是个人练习的话建议用微信测试平台(http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login )练习。


  云主机

  首先说下为什么需要云主机呢?

  开发微信公众号本质上和通常的网站开发并无区别。当我们进入一个公众号页面之后,我们可以向公众号发送文字、语音、图片等消息,也可以通过点击页面下方的菜单触发相应的功能。那么开发者与微信用户究竟是怎么进行交互的呢?实际上我们在公众号里的所有操作,都会发送到微信的服务器上,微信服务器将这些动作的具体含义按照一定的格式进行封装后,发送到微信公众号所对应的服务器上(这个服务器的地址可以由开发者在微信公众号的后台进行配置),开发者通过编写代码来处理不同的用户行为,并将处理后的结果按照一定的格式返回给微信服务器,再由微信服务器发送到微信公众号里面,从而完成了一次交互过程。在这里借用一张图片来展示下这个过程,可以帮助大家理解地更清楚:


开发者与用户的交互


  微信服务器和我们的公众号服务器通讯有个前提:两者需要彼此认证。这也是本文要讲的重点。


  首先要在公众号开发选项下面的基本配置里配置公众号开发信息和服务器配置信息。


公众号开发基础配置


  然后我们需要实现认证接口的代码,这里用Java演示。官方文档参考:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319

  接口代码如下:


@RestController
@RequestMapping("/auth/")
public class AuthController {

    private static final Logger LOGGER =LoggerFactory.getLogger(AuthController.class);

    @GetMapping("/handshake")
    public String handShakeAuth(
            @RequestParam(name = "signature") String signature,
            @RequestParam(name = "timestamp") String timestamp,
            @RequestParam(name = "nonce") String nonce,
            @RequestParam(name = "echostr") String echostr
    ) {
        LOGGER.info("signature:{},timestamp:{},nonce:{},echostr:{}",signature,timestamp,nonce,echostr);
        if(SignUtil.checkSignature(signature,timestamp,nonce)){
            return echostr;
        }
        throw new RuntimeException("非法请求");
    }
}


  认证逻辑如下:


package com.jack.wechat.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

/**
 * @author: jacky
 * @date: 2019/3/14
 */
public class SignUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(SignUtil.class);
    // 与接口配置信息中的 Token 要一致
    private static final String token = "jacky";

    /**
     * 验证签名
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] arr = new String[]{token, timestamp, nonce};
        // 将 token、timestamp、nonce 三个参数进行字典序排序
        Arrays.sort(arr);
        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 = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            LOGGER.error("Error msg:{}", e.getMessage());
        }

        content = null;
        // 将 sha1 加密后的字符串可与 signature 对比,标识该请求来源于微信
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }

    /**
     * 将字节转换为十六进制字符串
     *
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        String s = new String(tempArr);
        return s;
    }
}


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

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

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

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

  如果你是http协议的接口,端口号要记得设置为80。

  最后在云主机上搭建个web服务就好了。正常的话会提示你认证成功。否则检查下配置信息是否按微信要求的做了。比如:端口号,token等。