微信公众号H5页面自定义分享功能,JAVA后台签名算法实现,前端总是出现config:invalid signature.

问题描述

根据微信公众号网页服务的自定义分享服务接口的相关说明,我使用access_token获取到了ticket,后台再结合根据前端提交的时间戳(timestamp)、随机字符串(nonceStr)、url(JS接口安全域名)共4个参数,生成String1,再用SHA1加密得到签名signature,最后把这个签名signature返回给前端,可是前端在分享页面死活都是提示config:invalid signature.我已经晕了,不知道怎么处理了。请大神帮我看下代码,谢谢你。

问题出现的环境背景及自己尝试过哪些方法

按照官方的文档:“对所有待签名参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式”,我在服务器端代码里面对相应参数实现了ascII升序排序,微信公众号会报错;后来我看到官方提供的生成签名的沙盒,里面的String1并没有对参数进行AscII升序排序,我又把相关代码注释掉了,然后直接拼接,结果还是报那个错误。最后我直接使用沙盒里面的随机字符串和时间戳和最后生成的签名,任然报错。我真的不晓得到底怎么搞的。

相关代码

java 代码实现签名算法的部分

import java.security.MessageDigest;

public class WxSignatrueService {

private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

public static String getWxShareSignatrue(String ticket, String noStr, String url, String timestamp) {
    // char[] _ticket = ticket.toCharArray();
    // char[] _noStr = noStr.toCharArray();
    // char[] _url = url.toCharArray();
    // char[] _timestamp = timestamp.toCharArray();
    //
    // Arrays.sort(_ticket);
    // Arrays.sort(_noStr);
    // Arrays.sort(_url);
    // Arrays.sort(_timestamp);

    // String jsapi_ticket =
    // String.valueOf(_ticket)+"&noncestr="+String.valueOf(_noStr)+"&timestamp="+String.valueOf(_timestamp)+"&url="+_url.toString();

    String jsapi_ticket = "jsapi_ticket=" + ticket + "&noncestr=" + noStr + "&timestamp=" + timestamp + "&url="
            + url;
    
    return new String(encode(jsapi_ticket));
}    

private static String getFormattedText(byte[] bytes) {
    int len = bytes.length;
    StringBuilder buf = new StringBuilder(len * 2);
    // 把密文转换成十六进制的字符串形式
    for (int j = 0; j < len; j++) {
        buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
        buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
    }
    return buf.toString();
}

public static String encode(String str) {
    if (str == null) {
        return null;
    }
    try {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
        messageDigest.update(str.getBytes());
        return getFormattedText(messageDigest.digest());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

}

前端,在vue相关页面我是这样实现的:

mounted(){
    /* eslint-disable */
    let timestamp = Date.parse(new Date());
    let random = Math.random().toString(36).substr(2);
    let me = this;
    axios.get("https://我的域名/getSignature",{params:{noStr:random,url:"我的域名",timestamp:timestamp}}).then(res=>{
        wx.config({
            debug:true,
            appId:"appid",
            timestamp:timestamp,
            nonceStr:random,
            signatrue:res.data.data,
            jsApiList:["onMenuShareTimeline","onMenuShareAppMessage"]
        });
        wx.ready(function(){
            wx.onMenuShareTimeline({
                title:"我的专属房子",
                link:"我的域名",
                imgUrl:"我的域名"+me.backUrl,
                success:function(){

                }
            });
            wx.onMenuShareAppMessage({
                title:"我的专属房子",
                desc:"我的未来房子是这个样子",
                link:"我的域名/eaglepublic",
                imgUrl:"我的域名"+me.backUrl,
                success:function(){

                }
            })
        })

    })

你期待的结果是什么?实际看到的错误信息又是什么?

我期待在分享我的页面给朋友或者朋友圈的时候,能看到图标,并且不要提示那个错误,并且能进入我指定的link地址。
请问哪个有经验的大神能帮我解决这个问题。

阅读 5.4k
1 个回答

参与签名的url地址和你要分享的url地址是同一个吗?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题