微信jssdk 签名config:invalid signature排查
本文只涉及invalid signature 签名错误的排查过程。签名错误90%都是因为url造成的,按照如下步骤进行检查:
-
确认签名算法的正确性,可用https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=cardsign进行校验
-
确认config中的noncestr, timestamp与用以签名中的对应noncestr, timestamp一致 ,用于签名的字符串 nonceStr 不要超过32位
-
确认config的url是否是当前页面的url,这个是最容易发生错误的,接下来主要说明这一条.
在安卓中,url采用微信官方提供的方法
location.href.split('#')[0]
,基本没有问题;但是往往不会这么顺利,我碰到的一个传参比较奇怪的, 后端在从公众号跳转H5时使用了链接
https://yourhost.com/take?code=aaa:bbb
,传的参数带有“:
” 这种特殊符号,在地址栏上面会进行一次decodeURIComponent
,然后刷新地址,所以获取的url是https://yourhost.com/take?code=aaa%3Abbb
,签名校验的也是这个地址;在安卓没有问题,但是在
ios
当中,location.href.split('#')[0]
获取的是同样的路径,但是一测试居然报错了。几经周折,终于发现需要采用转码前的地址即https://yourhost.com/take?code=aaa:bbb
总结: 因为在iOS
下,微信需要你传递的是入口URL,而不是当前页面的URL!
延伸:微信内嵌浏览器在iOS
和安卓下的表现不一样。在安卓下,你确实用上面的方法是可以调用了。但是在iOS
下,签名依然失败!因为在iOS
下,微信需要你传递的是入口URL
,而不是当前页面的URL
!
比如说,你在微信公众号的某个菜单链接进入了A
页面,然后从A
页面的某个链接跳转到B
页面,然后你在B
页面获取签名,如果是在安卓下,你应该用B
页面的URL
地址来获取,但是在iOS
下,你还必须用A
页面的URL
地址来获取,否则就还是签名失败!
同样的,换一个场景,如果我们需要调用jssdk
的页面是B
,但是我们是通过A
页面的超链接过来的,我们需要把A
页面的路径缓存起来
if (navigator.userAgent.indexOf('iPhone') !== -1) {
window.wechaturl = window.location + '';
}
B
页面签名url
let url = window.location.href.split('#')[0];
if (window.wechaturl !== undefined) {
url = window.wechaturl;
}
在微信小程序的webview中同样如此,如果是以上场景也需要缓存
if (navigator.userAgent.indexOf('miniProgram') !== -1) {
window.wechaturl = window.location + '';
}