公众号签名问题
# 错误签名
核对官方步骤,确认签名算法。
- 确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。
- 确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。
- 确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)😕/'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。
- 确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。
- 确保一定缓存access_token和jsapi_ticket。
- 确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent,后台decodeURIComponent解码),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
签名是正确,上面的步骤还没能解决你的问题(invalid signature)那就用是url的问题,注意:微信公众号必须配置了你调试的安全域名(可以配置二级域名:xxx.com,而不用配置多个a.xxx.com/b.xxx.com等)。
原因:微信分享时候会给你当前页面添加多个参数,你sha1时候必须保证url地址是微信给你加了参数之后的地址,这样才不会报config:invalid signature.
解决方案:sha1之前url必须是解码之后的正常的肉眼直接能识别的url,如果你用的是静态页面,在你配置wx.config之前,先通过encodeURIComponent(location.href.split('#')[0])把当前url编码传递到后台,后台通过decodeURIComponent解码,核心代码如下:
# 前台html页面,编码传递url:
let title = '努力奋斗'
let desc = '把握机遇'
let imgUrl = 'http://p-cdn4.xx.com/9cf6e22e-bcc2-4bc4-b9cc-50c8732d7bdf?imageMogr2/auto-orient|imageMogr2/thumbnail/140x140'
let url = encodeURIComponent(window.location.href.split('#')[0])
axios.get(`https://api.xx.cn/api/wechat/sign?url=${url}`).then(res =>{
console.log('res', res)
const {data = {}} = res.data
const {timestamp, nonceStr, signature} = data
window.wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'xxx', // 必填,公众号的唯一标识
timestamp, // 必填,生成签名的时间戳
nonceStr, // 必填,生成签名的随机串
signature, // 必填,签名
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'checkJsApi',
], // 必填,需要使用的JS接口列表 ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage']
});
window.wx.ready(() => {
setWxShare(title, desc, imgUrl, 'http://code.xx.cn/wechat/');
});
function setWxShare(
title,
desc,
imgUrl,
link,
) {
// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
const dealLink = link || window.location.href;
window.wx.onMenuShareTimeline({
title, // 分享标题
link: dealLink, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl , // 分享图标
success: function() {
console.log('分享成功')
},
});
window.wx.onMenuShareAppMessage({
title, // 分享标题
desc, // 分享描述
link: dealLink, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl, // 分享图标
success: function() {
console.log('分享成功')
},
});
}
})
# 后台代码
let url = decodeURIComponent( this.post().url); //重点,解码前台传递url
//当前时间戳
let timestamp = parseInt( new Date().getTime()/1000);
//随机字符串
let nonceStr = Math.random().toString(36).substr(2,16);
# 账号主体
账号主体为个人时,无法使用分享接口
# 参考
上次更新: 2021/12/19, 18:05:42