微信二次分享报错invalidsignature问题及解决方法
问题现象描述
在进行微信二次分享时,发现页面出现了报错信息“invalid signature”,导致分享失败。无法正常将内容分享给朋友圈、微信群或者微信好友。
问题原因
微信二次分享的过程需要进行签名验证,如果签名不正确就会出现“invalid signature”错误。造成签名错误的原因有很多种,比如:
- 签名算法不正确
- 签名参数传递不正确
- 服务器生成的签名与微信服务器传回的签名不一致
- URL编码问题等
解决方法
1. 签名算法
在进行微信二次分享的签名算法中,有一个名为“jsapi_ticket”的参数需要加入签名。此参数是在微信端调用JS API时的必要参数之一,只有在页面调用JS API成功后,才可以获得这个参数。
以下是获取jsapi_ticket的过程:
- 在代码中调用微信提供的getJsApiTicket接口
wx.request({
url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token='+ACCESS_TOKEN,
success: function(res){
var ticket = res.data.ticket;
// 对获取到的ticket进行使用
}
});
- 在第一步中获取到jsapi_ticket后,还需要按照如下方式进行签名:
var string1 = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url;
var shaObj = new jsSHA("SHA-1", "TEXT");
shaObj.update(string1);
var signature = shaObj.getHash("HEX");
其中,noncestr是一段随机字符串,timestamp为当前时间戳,url为当前页面的URL地址。
2. 签名参数
在进行签名时需要注意一些参数的传递方式:
- URL参数需要进行urlencode,比如将“&”转换为“%26”,防止签名错误;
- 签名参数需要进行字典序排序,否则也会出现错误;
- 签名参数需要按照key=value的方式进行拼接,中间使用&符号连接。
以下为示例代码:
var noncestr = '123456'; // 随机字符串
var timestamp = Math.round(new Date().getTime()/1000).toString(); // 签名时间戳
var url = window.location.href.split("#")[0];
url = encodeURIComponent(url);
var signature = '';
// 字典序排序
var params = {
jsapi_ticket: jsapi_ticket,
noncestr: noncestr,
timestamp: timestamp,
url: url
};
var keys = Object.keys(params);
keys.sort();
// 拼接字符串
var string1 = '';
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = params[key];
if (string1.length === 0) {
string1 += (key + '=' + value);
} else {
string1 += ('&' + key + '=' + value);
}
}
// sha1签名
var shaObj = new jsSHA("SHA-1", "TEXT");
shaObj.update(string1);
signature = shaObj.getHash("HEX");
3. 服务器签名错误
当服务器生成的签名和微信服务器传回的签名不一致时,也会出现“invalid signature”错误。此时需要检查一下服务器生成签名的代码是否有问题,或者与微信服务器的时间戳不一致。如果服务器与微信服务器的时间戳不同,可以使用以下方法解决:
- 在请求微信JS SDK时,加上config参数并传递服务器时间戳
wx.config({
debug: false,
appId: '<%= appId %>', // 公众号唯一标识
timestamp: '<%= timestamp %>', // 必填,生成签名的时间戳
nonceStr: '<%= noncestr %>', // 必填,生成签名的随机串
signature: '<%= signature %>', // 必填,签名,见附录1
jsApiList: [
// 需要使用的JS接口列表
]
});
其中,appId是公众号的唯一标识,signature是通过上一步生成的签名字符串。
- 在签名算法中加入服务器时间戳
var string1 = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '×tamp=' + <%= timestamp %> + '&url=' + url;
示例代码
以下是一个完整的签名代码示例,包含了获取jsapi_ticket、进行签名以及调用微信JS SDK的代码:
function wxShare(){
var url = window.location.href.split("#")[0];
url = encodeURIComponent(url);
// 获取jsapi_ticket
wx.request({
url: '/api/getJsApiTicket',
data: {
url: url
},
success: function(res){
var jsapi_ticket = res.data.ticket;
var noncestr = '123456';
var timestamp = Math.round(new Date().getTime()/1000).toString();
var signature = '';
// 字典序排序
var params = {
jsapi_ticket: jsapi_ticket,
noncestr: noncestr,
timestamp: timestamp,
url: url
};
var keys = Object.keys(params);
keys.sort();
// 拼接字符串
var string1 = '';
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = params[key];
if (string1.length === 0) {
string1 += (key + '=' + value);
} else {
string1 += ('&' + key + '=' + value);
}
}
// sha1签名
var shaObj = new jsSHA("SHA-1", "TEXT");
shaObj.update(string1);
signature = shaObj.getHash("HEX");
// 调用微信JS SDK
wx.config({
debug: false,
appId: '<%= appId %>',
timestamp: timestamp,
nonceStr: noncestr,
signature: signature,
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
wx.ready(function(){
// 自定义分享内容
wx.onMenuShareTimeline({
title: '分享标题',
link: '分享链接',
imgUrl: '分享图标',
success: function () { },
cancel: function () { }
});
wx.onMenuShareAppMessage({
title: '分享标题',
desc: '分享描述',
link: '分享链接',
imgUrl: '分享图标',
type: '',
dataUrl: '',
success: function () { },
cancel: function () { }
});
wx.onMenuShareQQ({
title: '分享标题',
desc: '分享描述',
link: '分享链接',
imgUrl: '分享图标',
success: function () { },
cancel: function () { }
});
wx.onMenuShareWeibo({
title: '分享标题',
desc: '分享描述',
link: '分享链接',
imgUrl: '分享图标',
success: function () { },
cancel: function () { }
});
wx.onMenuShareQZone({
title: '分享标题',
desc: '分享描述',
link: '分享链接',
imgUrl: '分享图标',
success: function () { },
cancel: function () { }
});
});
}
});
}
总结
微信二次分享报错invalidsignature问题是一个比较常见的问题,但是它的错误原因和解决方法却比较复杂。在进行微信二次分享时,需要对签名的算法和传递参数进行仔细的检查,以保证签名的正确性。