解决微信JS-SDK扫一扫功能接入以及出现签名无效 invalid signature
最近一段时间由于业务需要在搞微信公众号开发,业务里面涉及到了微信公众号开发JS-SDK开发中扫一扫功能,由于没有之前没有这方面经验,首先肯定先仔细阅读微信开发文档了。
首先先说一下JS-SDK微信扫一扫功能接入方法:
开始时接入步骤,这里略带提一下,微信开发文档里面讲的很详细可以参考着写:
这里我重点说一下实现过程:
首先是页面上要引入相应的js文件,一行代码就足够了:
(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
然后通过config接口注入权限验证配置:
首先看微信开发官方文档上介绍的:
这里需要从服务器端网页面传递的参数有timestamp、nonceStr和signature而appId和jsApiList都是固定的,这里直接写后台方法中写。首先,编写服务器端代码,生成timestamp、nonceStr和signature。
在生成timestamp、nonceStr和signature的时候有两个参数需要获取 一个是access_token,另一个是jsapi_ticket。
access_token的获取需要AppId和AppSecret,获取位置如下:
获取地址如下,发送GET请求
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
获取到access_token的方法在这里就不说了 这个网上案例很多 一般是不会出什么大错的 只要appId和appsercret正确,地址正确就OK。
重点说一下jsapi_ticket的获取(这里我只说一下我自己的获取方法:):
在通用工具类CommonUtil里面写个获取jsapi_ticket的方法:
其的的JSAPI_TICKET是我定义的获取jsapi_ticket的地址:
public final static String JSAPI_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
方法:
然后根据获取到的access_token 调用此方法可获取到jsapi_ticket。
但是:
确保一定缓存access_token和jsapi_ticket。
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。
access_token和jsapi_ticket必须要在自己的服务器缓存,否则上线后会触发频率限制。请确保一定对token和ticket做缓存以减少2次服务器请求,不仅可以避免触发频率限制,请确保在服务上线前一定全局缓存access_token和jsapi_ticket,两者有效期均为7200秒,否则一旦上线触发频率限制,服务将不再可用。
详细的请仔细阅读文档。
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
上面的是微信开发文档中的签名生成规则:
具体生成过程代码可以不用自己写,微信开发文档提供的有demo示例:
是什么语言直接拿过来用就可以了!可以一边写一边琢磨签名算法的实现!
具体代码我就不贴出来了,基本上和上面的demo写的一样。
然后是Controller层的代码:
其中的JsApiTicketUtil.getJsApiTicket();是我从缓存中拿到的jsapi_ticket的键值对。
JsSignUtil.sign(jsapi_ticket,url); 就是demo中的获取签名的方法。
后台方法基本上完成了,接下来就是页面上的了:
在config中进行配置:
由于后台中生成的签名时间随机字符串什么的都是我在前台页面上用ajax获取到的,所有我写的配置为:
这个示例是我写微信扫一扫的示例。其中的jsApiList可以有很多值,微信开发文档上都用。
然后写一个简单的扫一扫按钮 写个触发事件:
接下来就是对自己写的进行测试了:
页面上功能按部就班的写完点击扫一扫没反应???只好把配置文件config的debug打开了。
发现每次打开页面总是会提示签名无效:
几乎整整一两天时间都再整这个bug,现在已经解决了,接下来我说说解决过程:
首先肯定是先看微信开发文档上给出的解决办法,这个也是一般非常常用的解决办法:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
截图:
如果出现签名无效 首先请按照官网文档上的方法一步步去排查,当然,排查过N次的同学就不用看了。
如果测试N次总是出现签名无效 ,那肯定是签名参数有问题。
如果用签名页面工具校验校验签名确实无误的话 ,那就是url的问题了。
微信开发文档常见错误报错上有这样一句话:
所以url要动态获取:可用location.href.split('#')[0]获取,而且需要encodeURIComponent,例如我写的:
然后后台获得还需要转换回来:
这是url的问题。一般这样写的话基本不会出什么错误了,要是还是出现签名无效,请继续往下看;
请确认你的AppId和AppSecret正确性;
确定通过AppId和AppSecret获取到的access_token全局缓存了并且有效。
确认获取到的jsapi_ticket是有效的 用到的access_token和appid是正确的。
确认获取access_token和jsapi_ticket的地址为:
请一定要仔细检查这个地址url,最好和官网文档上的对着一遍,看清楚是获取什么的地址栏!
最后再补充一点:
在查找错误的时候,我在百度上看到有人这样说:
上面的两个方法:是签名算法中的随机数和时间戳,首先请注意时间单位是秒 不是毫秒,其次是上面的随机数,官网文档上用的UUID获取的随机数,但是网上有人说必须是16位的,我这里写的也是16位的,如果经过上面的还报错的话
可以试试是不是这个的问题。
给个微信开发文档的路径:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432