实现微信分享springboot后端demo

前言

微信的开发文档写的像一坨屎,并且只有php的demo,非常不友好

api简介

前端通过jsapi调用微信接口之前,都需要初始化,主要需要appId, timestamp, noceStr, signature,其中appId是静态的,由公众号后台提前配置好,timestamp, noceStr, signature都是动态的,一般通过java后端通过接口来提供,因此本文的重点就是后端如何处理获取并返回timestamp, noceStr, signature

image.png

主要流程

  • 1、申请一个公众号
    过程省略
  • 2、获取appId和appSecret
    进入公众号后台,点击开发 -> 基本配置
    基本配置

    页面会提示你是否成为开发者,走正常输入密码/微信扫码流程,成功后会自动分配一个appID,开发者密码需要手动配置,配置完成后,设置后端调用接口获取access_token的IP白名单(该ip为后端服务所部署的服务器所在的ip,必须设置,否则无法获取access_token)
    开发信息
  • 3、服务器配置
    需要填写URL和Token(自定义),EncodingAESKey可以随机生成。
    服务器配置

    填写的URL需要用备案过的域名(免费的内网穿透的域名似乎不行),并且必须是80端口,需要我们写一个接口,并部署在域名下,URL对应接口的访问路径。在点击下面的提交按钮时,微信会发一个GET请求到这个接口,包括四个字符串:
    signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    timestamp 时间戳
    nonce 随机数
    echostr 随机字符串
    我们的接口需要接受这四个参数,用微信指定的验证方式对参数进行校验,校验方式如下:
    1)将token、timestamp、nonce三个参数进行字典序排序
    2)将三个参数字符串拼接成一个字符串进行sha1加密
    3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
    若校验成功,则接口需要返回echostr参数内容。
    JAVA代码:
/**
* WxRequest是一个包含了微信传过来的四个参数的实体类,返回true表示验证成功
**/
public boolean valid(WxRequest request){
        String signature = request.getSignature();
        String timestamp = request.getTimestamp();
        String nonce = request.getNonce();
        String echostr = request.getEchostr();
        
        String token = "你在配置页面填写的Token";

        String[] arr = new String[]{token, timestamp, nonce};
        Arrays.sort(arr);
        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        StringBuilder content = new StringBuilder();
        for (String anArr : arr) {
            content.append(anArr);
        }

        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] digest = md.digest(content.toString().getBytes());
        tmpStr = byteToStr(digest);
        return tmpStr != null && tmpStr.equals(signature.toUpperCase());
}


private static String byteToStr(byte[] byteArray) {
        StringBuilder strDigest = new StringBuilder();
        for (byte aByteArray : byteArray) {
            strDigest.append(byteToHexStr(aByteArray));
        }
        return strDigest.toString();
    }

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];
        return new String(tempArr);
    }
  • 4、配置js安全域名
    点击微信公众号后台右上角,选择功能设置

    image.png

    设置js安全域名,微信需要判断js调用接口的域名是否是经过我们的配置,并且安全,这个域名指的是微信分享页面所处的域名
    image.png

    首先需要将红色框框里的文件下载下来,放到域名对应的根目录下(也可以指定目录),然后填写域名(内网穿透的临时域名同样不可用)。在点击保存的时候,微信会到这个域名下寻找我们放置到根目录中的下载文件并验证
    image.png

  • 5、获取前端所需的三个参数
    服务器配置完以后,表示appID和appSecret正式生效,前端也有了调用jsapi的权限,把appID交给前端,就可以开始写三个参数的获取接口了。
    其中noncestr(随机字符串)和timestamp都是我们自定义的,signature则需要通过Http向微信请求,也就是说问题重点转化为如何获取signature。
    获取signature主要分三步:

    • ① 获取access_token
      通过get请求访问https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,参数说明如下:
      grant_type 获取access_token填写client_credential
      appid 第三方用户唯一凭证
      secret 第三方用户唯一凭证密钥,即appsecret
      返回内容是包括access_token和expires_in(单位秒)两个字段的json字符串,由于每天获取access_token的次数有限,一般需要将其缓存起来
    • ② 获取ticket
      get请求https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
      返回内容是包含了errcode、errmsg、ticket、expires_in(单位秒)字段的json字符串
    • ③ 生成signature
      签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。
      对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
      这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
      具体的java代码可以看这里
      如果不确定自己生成的签名是否正确,可以到微信官方signature验证

你可能感兴趣的:(实现微信分享springboot后端demo)