问题效果如下
返回错误详细信息
errMsg: "config:fail,Error: 系统错误,错误码:63002,invalid signature [20201105 15:06:48][]"
通过config接口注入权限验证配置ready方法一直返回错误。
接口文档地址: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4
遗憾这里这有前端的文档调用说明,没找到后台调用获取jsapi_ticket的方法。
后台用java调用获取如下参数:
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
后台java调用
package com.cciinet.shop.controller.common.wechat;
import com.alibaba.fastjson.JSONObject;
import com.cciinet.shop.util.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;
/**
* @Author:
* @Date: 2020/6/10
* @ClassName: Sign
* @Description: TODO
**/
@Slf4j
public class Sign {
/**
* jsSdk 获取微信config
*
* @param url
* @return
*/
public JsSdk sign(String url,String appId, String appsecret) {
String jsapi_ticket = getJsapiTicket(appId,appsecret);
JsSdk jsSdk = new JsSdk();
jsSdk.setAppid(appId);
jsSdk.setUrl(url);
String nonce_str = create_nonce_str();
jsSdk.setNoncestr(nonce_str);
String timestamp = create_timestamp();
jsSdk.setTimestamp(timestamp);
String signature = "";
//注意这里参数名必须全部小写,且必须有序
String string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
jsSdk.setSignature(signature);
} catch (NoSuchAlgorithmException e) {
jsSdk = null;
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
jsSdk = null;
e.printStackTrace();
}
return jsSdk;
}
/**
* 生成随机数
*
* @return
*/
private static String create_nonce_str() {
return UUID.randomUUID().toString().substring(0, 20);
}
/**
* 当前日期字符串生成
*
* @return
*/
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
/**
* @param hash
* @return
*/
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
public String getJsapiTicket(String appId, String appsecret) {
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token";
String params = "grant_type=client_credential&appid=" + appId + "&secret=" + appsecret+ "";
String result = HttpRequest.sendGet(requestUrl , params);
String access_token = JSONObject.parseObject(result).getString("access_token");
requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
params = "access_token=" + access_token + "&type=jsapi";
result = HttpRequest.sendGet(requestUrl , params);
String jsapi_ticket = JSONObject.parseObject(result).getString("ticket");
log.info("jsapi_ticket=" + jsapi_ticket);
return jsapi_ticket;
}
public static void main(String[] args) {
Sign sign = new Sign();
String appId = "";
String appSecret = "";
// String jsapiTicket = sign.getJsapiTicket(appId, appSecret);
// System.out.println(jsapiTicket);
String url = "";
JsSdk jsSdk = sign.sign(url, appId, appSecret);
System.out.println(jsSdk.toString());
}
}
其中main方法里输入自己公众号的appid,secret,和分享要调用的url。调用即可拿到返回值。 大坑来了,我的问题是用后代代码生成的signature和用微信在线调试工具生成的signature是一样的。
微信在线调试地址:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
但仍然提示签名错误。奇了怪了。
最后发现是我程序后台调用生成签名传入的url不对。
传入的url应该是当前要分享的页面的完整url,网上还有好多说要在url后边加上个“/”个,这个也不对,不应该加斜杠的。
总结一下: 这个报签名不对的原因,并不是后台代码调用微信接口返回signature和在线微信调试生成的signature对不上。而是实际调用微信接口页面地址和生成签名传入的url对不上导致的。
看下接口说明,后台调用微信接口的文档没找到o(╯□╰)o
这里明确说明了是发起页面的完整url.。