2023年11月28日发(作者:)
微信公众号中的JSSDK接⼊及invalidsignature等常见错误问
题分析(全⾯解析)
最近在搞微信公众号开发,进⾏到⽹页开发部分被坑了⼀天,最坑的问题就是invalid signature,⽽⽹上⼤部分解答这个问题的都没有
说清楚,都直接丢⽂档。博主认为这样很不好。本⽂是博主结合⾃⾝遇到的问题所写,整个流程跟问题都很详细,虽然排版可能有点
不好。但是绝对对遇到类似问题的朋友有所帮助。请认真看下去
⼀、绑定JS接⼝安全域名
⼆、引⼊微信js⽂件
三、通过接⼝注⼊权限验证
1、每个需要使⽤jssdk的页⾯都要使⽤config接⼝注⼊配置信息,调⽤⽅法如下:
({
debug: true, // 开启调试模式,调⽤的所有api的返回值会在客户端alert出来,若要查看传⼊的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯⼀标识
timestamp: , // 必填,⽣成签名的时间戳,精确到秒
nonceStr: '', // 必填,⽣成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使⽤的JS接⼝列表,例如:['chooseImage','previewImage','uploadImage']
})
其中必须从后台获取
appId,timestamp,nonceStr,signature
四、后台⽣成并返回前端所需参数
1、jsapi_ticket
jsapi_ticket是公众号⽤于调⽤js接⼝的临时票据。有效期7200秒,跟公众号普通access_token⼀样,必须全局缓存起来,因为这个
ticket获取次数有限,超过次数将⽆法使⽤。建议设置缓存时间为7198秒,因为当请求微信端⽣成jsapi_ticket返回给后台保存这个动作
需要时间,如果设置7200秒,实际上最后⼀两秒时,缓存⾥⾯还存在,但实际在微信那边已经过期了,再拿这个ticket会出错。⽣成
jsapi_ticket如下:
(1)获取普通access_token(GET请求):
(2)⽤第⼀步获取的access_token使⽤GET请求获取jsapi_ticket
正确获取信息如下:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
2、⽣成签名(signature)
签名规则:
1、参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前⽹页的URL,不包含#及其后⾯
部分)。
2、对所有待签名参数按照字段名的ASCII 码从⼩到⼤排序(字典序,sort()即可)后,使⽤URL键值对的格式(即
key1=value1&key2=value2…)拼接成字符串(string)。
3、使⽤sha1加密拼接成的字符串string。
注意:字段名和字段值都要使⽤原值,不要进⾏url转义
参与的字段⽰例:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=?params=value
拼接完成的字符串:
使⽤sha1加密后的signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
3、签名⽣成完后将appId、timestamp、nonceStr、signature⼀起返回到前端。格式⽰例:
{
appId:appId,
timestamp:timestamp,
nonceStr: noncestr,
signature: signature
}
前端拿到值后,写⼊到中相应字段即可
注意:
1、前端配置中的nonceStr字段名称的's'是⼤写。但是后台⽣成签名的noncestr字段的‘s'是⼩写,千万要注意,博主在这⾥浪
费了不少时间。囧囧
2、时间戳(timestamp)值要记住精确到秒,不是毫秒。
3、⽣成签名的url(使⽤jssdk的页⾯地址,这个页⾯地址可以在浏览器访问),包含“?”号后⾯的所有参数,不包含“#”号后⾯的值。
如果是静默授权或者授权页⾯同意授权后跳转到的页⾯,页⾯路径会添加两个参数:code和state。
那么⽣成签名的url必须为授权后跳转页⾯的完整路径。前端获取这个路径:
('#')[0]
注意注意:这⾥有个⼤坑。。如果前端使⽤ajax(使⽤jquery)获取配置所需的⼏个参数的值,可以这样做:
$.ajax({
url: '?fullUrl=' + ('#')[0], //这⾥的参数fullUrl是当前页⾯的完整url(除去#后⾯部分)
type: 'GET',
success: function(res) {
//操作后台返回值
}
})
后台要怎么操作前端传过来的query值呢?⼤家肯定⼀眼看出来 获取query中的fullUrl字段不就⾏了。
博主也是这么做的,请看博主后台代码(使⽤nodejs的koa框架)
let query = ;//获取查询字符串
let fullUrl = l;//获取查询字符串中的fullUrl字段
怎么样,有没有看出什么不对劲的地⽅?没有?
博主把所有后续的获取access_token、jsapi_ticket、计算签名、返回值到前端、前端配置好这些所有操作做完,信⼼满满的
开始⽤测试号访问页⾯。结果直接弹出config: invalid signature(开启debug模式)。WTF
当然,搞这⼀⾏早就做好了遇到问题的⼼理准备。。。。开始排错呗。。
⾸先在后台将获取access_token、jsapi_ticket、计算签名的参数字典序排序后的字符串、sha1加密后的字符串全部出来。
发现,没有错误的地⽅。那⾏,看来有可能是我代码那个地⽅写错了,或者签名算错了?
到微信在线接⼝调试把刚刚打印的计算签名的⼏个参数分别填好。⽣成。。。发现跟我的代码⽣成的是⼀样的。
结果博主是各种排错,各种百度,各种google。结果还是config: 此处省略博主⼼⾥⼀万句话
⼜这样过了⼀个多⼩时,⽆果。。。。。。博主⼀脸颓废的到茶⽔间泡了杯咖啡。。提提神。。⼜回到了岗位,准备从头开始跑⼀遍
再仔细看看。
从前端请求获取签名接⼝开始,博主打印了query的值。。也就是let query = 的值。。结果发现。query值为:
{
fullUrl: '?code=kdijafdhjaikeiu20kaiela',
state: 'STATE'
}
好吧,问题在这⾥,有没有⼈早就看出来的?前⾯说过,微信⽹页授权后跳转的页⾯完整路径为
有没有注意路径最后⾯的'&state=STATE'。当我们把这个完整路径当做查询字符串传到后台的时候,因为没有对这个路径进⾏
encodeURIComponent.所以后台将'&state=STATE'单独看成了⼀个查询字符串参数,问题点在这⾥。。
后来查看公众号⽂档发现'附录5-常见错误及解决⽅法'第六条有说明
问题解决
使⽤即可
encodeURIComponent(('#')[0])
五、调⽤接⼝
配置完成后会执⾏⽅法,所有接⼝必须要在config返回结果之后操作。config是⼀个客户端的异步操作,所以如果需
要在页⾯加载时就调⽤相关接⼝,则须把相关接⼝放在ready函数中调⽤来确保正确执⾏。对于⽤户触发时才调⽤的接⼝,则可以直接
调⽤,不需要放在ready函数中。当前页⾯要使⽤的接⼝,要写⼊到config配置中的jsApiList中
1、拍照或从⼿机相册中选图接⼝
mentById('chooseImage').onclick = function(){
Image({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认⼆者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认⼆者都有
success: function (res) {
var localIds = ds; // 返回选定照⽚的本地ID列表,localId可以作为img标签的src属性显⽰图⽚
}
});
}
六、常见问题
1、invalid url domain:
js接⼝安全域名错误。可以看看第⼀项
2、invalid signature:
要么是jsapi_ticket错误,要么是签名算法问题,要么是算法的参数有问题,注意noncestr中的's'是⼩写的。如果都是对的。那就是前端
传的url有问题了。。。好好检查⼀下,不要像博主⼀样啊。。。。
3、permission denied:
这个问题⼀般是没有接⼝权限的问题,有的接⼝是要认证之后才可以使⽤,当然,测试号不会有这个问题
总结
到此这篇关于微信公众号中的JSSDK接⼊及invalid signature等常见错误问题分析(全⾯解析)的⽂章就介绍到这了,更多相关微信公众号
JSSDK接⼊invalid signature错误内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
发布评论