前言
微信的开发文档写的像一坨屎,并且只有php的demo,非常不友好
api简介
前端通过jsapi调用微信接口之前,都需要初始化,主要需要appId, timestamp, noceStr, signature,其中appId是静态的,由公众号后台提前配置好,timestamp, noceStr, signature都是动态的,一般通过java后端通过接口来提供,因此本文的重点就是后端如何处理获取并返回timestamp, noceStr, signature
主要流程
- 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验证
- ① 获取access_token
网友评论