02. 微信公众号验证接入

1. 公众号 微信公众号开发文档
  1. 区别
    在这里插入图片描述
    在这里插入图片描述

  2. 选择

    1. 如果想简单的发送消息,达到宣传效果,建议可选择订阅号;
    2. 如果想用公众号获得更多的功能,例如开通微信支付,建议可以选择服务号;
    3. 如果想用来管理内部企业员工、团队,对内使用,可申请企业号;
    4. 订阅号可通过微信认证资质审核通过后有一次升级为服务号的入口,升级成功后类型不可再变;
    5. 服务号不可变更成订阅号。
  3. 测试号

    专门为开发人员准备的一种仅用于测试的公众号,部分高级功能不支持,如微信支付、卡券等

    测试号申请链接

2. 开发
  1. 微信测试号

    1. 测试号信息

      1. appID是公众号开发识别码,配合appsecret可调用公众号的接口能力。
      2. appsecret是校验公众号开发者身份的密码,具有极高的安全性。
      3. 两者是比较重要的信息,不得随意发给别人
      4. 如果是正式的公众号,登录公众平台官网之后,找到基本配置菜单栏也可以获取到公众号相关的信息
    2. 接口配置信息

      1. URL是我们自己的服务器访问地址 --> 必须以http:// 或 https:// 开头,分别支持80、443端口

        1. 响应微信发送的 Token 验证
        2. 用来接收、响应微信公众号关注者发送的信息、事件
      2. Token可随意填写,用来生成签名 --> 3-32位的英文、数字组成的字符

  2. 微信与服务器交互

    1. 公众号关注者发送信息 --> 发送到微信的服务器上
    2. 微信的服务器对内容封装成 xml 等格式 --> 转发到我们填写的 URL 上,即该URL实际就是我们处理数据的一个请求路径
    3. 我们的服务器回复 xml 等格式数据 --> 微信的服务器
    4. 微信的服务器 --> 响应到 公众号关注者
  3. URL验证接入 官方文档

    1. 填写 URLToken --> 提交

    2. 微信服务器将发送GET请求到填写的服务器地址URL上,并携带以下4个参数

      参数描述
      signature微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
      timestamp时间戳
      nonce随机数
      echostr随机字符串
    3. 开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败

    4. 加密/校验流程

      1. 将token、timestamp、nonce三个参数进行字典序排序
      2. 将三个参数字符串拼接成一个字符串进行sha1加密
      3. 开发者获得加密后的字符串可与signature对比,两者相等则标识该请求来源于微信
      
  4. 代码

    1. controller

      import com.small.nine.wxmp.service.WeiXinService;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.RestController;
      
      import javax.annotation.Resource;
      
      /**
       * 微信公众号相关服务 API
       *
       * @author sheng_zs@126.com
       * @date 2021-07-26 9:07
       */
      @Slf4j
      @RestController
      @RequestMapping("/wx")
      public class WeiXinController {
          @Resource
          private WeiXinService weiXinService;
      
          /**
           * 微信接入,验证是否是微信发送的信息
           *
           * @param signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
           * @param timestamp 时间戳
           * @param nonce     随机数
           * @param echoStr   随机字符串
           * @return 验证成功返回 echoStr
           */
          @GetMapping("/weChat")
          public String checkSignature(@RequestParam String signature, @RequestParam String timestamp,
                                       @RequestParam String nonce, @RequestParam("echostr") String echoStr) {
              return weiXinService.checkSignature(signature, timestamp, nonce, echoStr);
          }
      }        
      
    2. service

      /**
       * 微信公众号相关API服务层
       *
       * @author sheng_zs@126.com
       * @date 2021-07-26 9:22
       */
      public interface WeiXinService {
          /**
           * 微信接入,验证是否是微信发送的信息
           *
           * @param signature 加密后的字符串
           * @param timestamp 时间戳
           * @param nonce     随机数
           * @param echoStr   返回的字符串
           * @return 满足条件返回 echoStr
           */
          String checkSignature(String signature, String timestamp, String nonce, String echoStr);
      }
      
    3. impl

      import cn.hutool.core.util.HexUtil;
      import cn.hutool.core.util.StrUtil;
      import cn.hutool.crypto.digest.DigestUtil;
      import cn.hutool.crypto.SecureUtil;
      import com.small.nine.wxmp.config.WxConfig;
      import com.small.nine.wxmp.service.WeiXinService;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.stereotype.Service;
      
      import javax.annotation.Resource;
      import java.util.Arrays;
      import java.util.Objects;
      
      /**
       * @author sheng_zs@126.com
       * @date 2021-07-26 9:24
       */
      @Slf4j
      @Service
      public class WeiXinServiceImpl implements WeiXinService {
          @Resource
          private WxConfig wxConfig;
      
          @Override
          public String checkSignature(String signature, String timestamp, String nonce, String echoStr) {
              log.info("微信接入:signature={}, timestamp={}, nonce={}, echoStr={}", signature, timestamp, nonce, echoStr);
              return checkToken(signature, timestamp, nonce, wxConfig.getToken()) ? echoStr : "";
          }
      
          /**
           * 验证 signature 是否与 token、timestamp、nonce 三个字符串"字典排序后"拼接成一个字符串进行"sha1加密"的字符串相等
           *
           * @param signature 加密后的字符串
           * @param timestamp 时间戳
           * @param nonce     随机数
           * @param token     填写的 token
           * @return 验证成功返回 true
           */
          private boolean checkToken(String signature, String timestamp, String nonce, String token) {
              if (StrUtil.hasBlank(signature, timestamp, nonce, token)) {
                  throw new IllegalArgumentException("微信公众号非法请求参数,请核实");
              }
              // 1. 将token、timestamp、nonce三个参数进行字典序排序
              String[] strArr = new String[]{timestamp, nonce, token};
              Arrays.sort(strArr);
              // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
              StringBuilder builder = new StringBuilder();
              for (String s : strArr) {
                  builder.append(s);
              }
             // 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
      //        return Objects.equals(signature, HexUtil.encodeHexStr(DigestUtil.sha1(builder.toString())));
              return Objects.equals(signature, SecureUtil.sha1(builder.toString()));
          }
      }
      
    4. WxConfig

      import lombok.Getter;
      import lombok.Setter;
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.context.annotation.Configuration;
      
      /**
       * 微信配置类
       *
       * @author sheng_zs@126.com
       * @date 2021-08-02 15:51
       */
      @Getter
      @Setter
      @Configuration
      @ConfigurationProperties("wx")
      public class WxConfig {
          /**
           * 微信公众号 ID
           */
          private String appID;
      
          /**
           * 微信公众号 appSecret
           */
          private String appSecret;
      
          /**
           * token
           */
          private String token;
      }        
      
  5. 源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值