javascript - 微信公众平台, config:invalid signature一直爆这个错误,求教如何解决?


然后哦 用这个校验和输出的是一致的也就是说 签名应该没问题吧 但是为什么手机上会显示无效呢 那个环节又出错了

提问者PHPzhong提问时间:2017-04-11 13:13我来回答
44回答
ringa_lee
回复ringa_lee赞同06个月前

1.确认签名算法正确,可用 http://mp.weixin.qq.com/debug... 页面工具进行校验。

    2.确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。

    3.确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。

    4.确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。

    5.确保一定缓存access_token和jsapi_ticket。

    这个是重点:
    确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。

    教如何验证是否正确方法:
    url动态获取的方法是:
    $protocol = (!empty($_SERVER[HTTPS]) && $_SERVER[HTTPS] !== off || $_SERVER[SERVER_PORT] == 443) ? "https://" : "http://";
      $url = $protocol.$_SERVER[HTTP_HOST].$_SERVER[REQUEST_URI];
    大家讲道理
    回复大家讲道理赞同06个月前

    我的在url 后面漏了一个“=”,找了好久啊
    url: PRJ_PATH + '/jsapi.json?url=' + url

      PHP中文网
      回复PHP中文网赞同06个月前

      今天遇到了同样问题
      不能全部按着文档来做

        Peter Zhu
        回复Peter Zhu赞同06个月前

        今天也是遇到这个问题,最终解决了。
        原因也是在url地址上。通过php传递的url地址是"http://.....",而在页面上alert(window.location.href);显示的是https://....。
        我这边的原因是粗心造成的,不知道你们是不是没注意到这里。

          黄舟
          回复黄舟赞同06个月前

          这两天也是被这个问题折磨了很久,各位如果有问题的不妨看看你们的config里的timestamp的类型,从后台拿到的是String需要转成数值类型.

            黄舟
            回复黄舟赞同06个月前

            我的也出现这种问题,但是我的这种问题只出现在ios9以上,安卓的完全正常,ios有时候正常 有时候不正常,不正常的时候我也用签名工具验证了,但还是不行,url我也比对了 都是完全一样的 实在搞不清,求大神指点 跪求 希望大神看到后指点一下 万分感谢

              猪哥
              回复猪哥赞同06个月前

              @docejack 正解,页面当前的url一定要和签名用的url一致

                刘奇
                回复刘奇赞同06个月前

                一次就成功的路过。。

                  伊谢尔伦
                  回复伊谢尔伦赞同06个月前

                  不行,我文件名也放出来了,也是对的,还是一样报错,不知道问题出在哪,太坑了

                    PHPzhong
                    回复PHPzhong赞同06个月前

                    楼主,你这个问题解决了吗?我也碰到这个问题了,好纠结啊!

                      迷茫
                      回复迷茫赞同06个月前

                      也是这个问题,蛋都碎了......

                        PHPzhong
                        回复PHPzhong赞同06个月前

                        引起这个问题的原因是什么呢?我们也遇到了困扰,但是没有找到问题所在。
                        希望看到的朋友指点~~

                          ringa_lee
                          回复ringa_lee赞同06个月前

                          也提供一个解决方法,url和签名多次检查没有错误,开始一直根据文档提示可用location.href.split('#')[0]获取,而且需要encodeURIComponent。不用encodeURIComponent转义,之后请求OK。只能说无语了

                            ringa_lee
                            回复ringa_lee赞同06个月前

                            碰到了同样的问题(并“解决”了):

                            问题描述:

                            1. 单页面应用(使用pushState更新url),iOS 10或Android 6.0

                            2. 同样的web代码和网址,使用安卓访问,能正常调用微信API注册并分享;使用iOS 10则注册失败,返回'invalid signature'

                            3. signature生成算法没有问题。(将输入和输出贴到微信提供的验证网页上,都一致)

                            调查发现:

                            1. 安卓需要使用当前URL进行微信API注册(即当场调用location.href.split('#')[0])

                            2. iOS需要使用进入页面的初始URL进行注册,(即在任何pushstate发生前,调用location.href.split('#')[0])

                            解决(规避):

                            1. 保存进入页面最初的URL,假设为INIT_URL

                            2. 根据客户端的不同:
                              2.1 安卓:在准备分享前(或发生URL跳转后)使用当前URL进行wx.config, 如果失败,则尝试使用INIT_URL注册

                            2.2 iOS:在准备分享前(或发生URL跳转后)使用INIT_URL进行wx.config, 如果失败,则尝试使用当前URL注册

                            结论:

                            1. 感觉没有找到问题的真相。。。。

                              巴扎黑
                              回复巴扎黑赞同06个月前

                              如果是第三方公众号开发者,在使用JS SDK时获取ticket(https://api.weixin.qq.com/cgi...)时的请求参数access_token要使用authorizer_access_token。
                              由于我之前使用的第三方公众号component_access_token导致出现了楼主类似的问题。

                                阿神
                                回复阿神赞同06个月前

                                本地程序生成的 签名 跟 官网通过的签名工具生成的签名 对比是一致的,但还是提示 invalid signature , 请试试看把access_token.json跟jsapi_ticket.json内容都清空

                                  猪哥
                                  回复猪哥赞同06个月前

                                  使用的是官网提供JS-SDk PHP Demo,出现invaild signature 打印地址时发现url为http://

                                  解决办法:在类文件jssdk.php中修改$url

                                  public function getSignPackage($host,$uri) {
                                  $url = "http://".$host.$uri;
                                  ......
                                  }
                                  \\\\$jssdk->GetSignPackage($_SERVER['HTTP_HOST'],$uri = $_SERVER['REQUEST_URI']);
                                    Peter Zhu
                                    回复Peter Zhu赞同06个月前

                                    大概就是当前URL和生成签名的URL不一致问题吧,说下我的问题。我用ajax请求的后台config参数,和LZ一样,签名没问题但是signature还是不可用,微信官方的文档里面的错误都筛过了,后来发现导致URL不一致的原因是GET和POST请求的问题,GET请求无法获取URL中&后的参数,导致URL不一致。So,很蠢的错误,但是可能也是比较容易被忽略的吧

                                      Peter Zhu
                                      回复Peter Zhu赞同06个月前

                                      遇到这个问题 已经解决 方案来自本站网友 疯狂的蜗牛

                                      问题:获取微信的jsapi_ticket有两个URL地址
                                      一个是:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=wx_card
                                      另一个是:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi
                                      注意后面的type

                                      我用成了第一个type=wx_card微信卡券的地址 改用用第二个地址type=jsapi。。问题解决

                                      你可以检查下是不是这个问题

                                        猪哥
                                        回复猪哥赞同06个月前

                                        我给说一下我微信分享二次签名遇到的问题,我后台获取参数时候出的问题,原来通过map遍历参数,然后在拼接一下,导致参数顺序不对,签名有误。
                                        改正后的方式如下:

                                        if(request.getQueryString()!=null) {
                                                uri+="?"+request.getQueryString(); 
                                            }

                                        再次签名就正确了。主要原因还是签名的url和alert(location.href.split('#')[0])的url不一致。

                                          ringa_lee
                                          回复ringa_lee赞同06个月前

                                          timestamp也要检查一下

                                            ringa_lee
                                            回复ringa_lee赞同06个月前

                                            我今天也碰到了这个问题,各种参数与签名均一致,但就是报签名错误。

                                            最后你猜怎么着,最后居然发现是因为页面中有一个嵌套了腾讯视频的 iframe ,因为 js 对 iframe 大小进行调整时改变了 src 值导致 iframe 上一个请求被取消并再次加载,然后就导致微信 js 接口报 invalid signature 的错误了。

                                            最后去掉了 iframe 自带的 src 属性,等 js 调整好大小后一次性加载,就解决了。

                                            奇葩吧,一个 iframe 里嵌套的视频,看上去毫不相关的东西居然影响了微信的 js 接口的签名验证。

                                              伊谢尔伦
                                              回复伊谢尔伦赞同06个月前

                                              当前url:http://www.xx.cn/h5/share.html 非常简单,生成签名的url一致.

                                              微信校验签名也通过

                                              代码部分如上,

                                              可在微信里却还一直报invalid 签名!!
                                              从上看到下,没找到这类问题的实际解决方案和原因!求指教啊!!

                                                伊谢尔伦
                                                回复伊谢尔伦赞同06个月前

                                                这两天也遇到这个问题,查了两天发现是一个特别二的失误:
                                                我一直把开放平台的appid当作公众平台的在用,直到我膝盖中了一箭……

                                                  小葫芦
                                                  回复小葫芦赞同06个月前

                                                  注意jsapi_ticket的生成,别调到卡券ticket的生成接口了,type要传"jsapi"
                                                  https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

                                                    小葫芦
                                                    回复小葫芦赞同06个月前

                                                    遇到一次因为URL里有横杠,也是报invalid signature。去掉之后就过了,大概是哪个环节对特殊字符转义不一致吧

                                                      迷茫
                                                      回复迷茫赞同06个月前

                                                      我也出了这个问题了,签名和官方测试接口一模一样,后来发现是打开的页面URL和分享的不一样的问题,但是改成一样的还是不可以。这时候看了另一个贴share112的回复,把 jsapi_ticket 和 access_token 这两个文件删掉,从新打开页面,就解决了!!希望能帮到后人

                                                        迷茫
                                                        回复迷茫赞同06个月前

                                                        这个我刚刚搞定了这个问题...还是看来上面的以为仁兄的回答.就是url那点!你在微信上面绑定的URL一般都是没有带端口号的,但是你直接用demo里面的url是带了端口号的...所有把这个$url = "$protocol$_SERVER[SERVER_NAME]$_SERVER[REQUEST_URI]";这个就行了! 还有把手机缓存给清了!!!!!

                                                          迷茫
                                                          回复迷茫赞同06个月前
                                                          /*
                                                          		langdr  
                                                          		wx70a830814a88****
                                                          		356d50570cbeb75a******
                                                              	*/
                                                          
                                                                  /*
                                                                  blog
                                                                  wx2c9b85307c8b****
                                                                  ae72e94d11c5250804e3****
                                                                  */
                                                          
                                                              	//wxc31521770***
                                                              	//da4815941b5626240b********
                                                                  $jssdk = new \Think\Jssdk("wxc31521770******","da4815941b5626240bc271ac*******");
                                                                  $signPackage = $jssdk->GetSignPackage();
                                                                  dump($signPackage);
                                                                  $this->assign("signPackage",$signPackage);
                                                                  // dump($signPackage);
                                                                  $this->display();

                                                          求助 langdr 和 blog 是未认证订阅号,可以启用微信js,可是一旦换成第三个已认证服务号就提示签名失败!!!!有没人可以告诉我原因 万分感谢!!

                                                            阿神
                                                            回复阿神赞同06个月前

                                                            签名和官方的一样、 URL也是通过location.href.split('#')[0]获取的。。 也是一直提示 config:invalid signature 公众号的JS接口安全域名也是配置OK,就是不行。。 求大神帮助、
                                                            测试地址:http://weixin.zhjckx.com/ApiWeiXin/JsSdk

                                                              阿神
                                                              回复阿神赞同06个月前

                                                              醉了,签名都是一样的 还是问答 config:invalid signature

                                                                猪哥
                                                                回复猪哥赞同06个月前

                                                                我也遇到了这个问题 搞了好久 终于解决了。是从微信上过来的URL没有带文件名。而通过微信浏览器打开后自动加上了默认文件名 index.php 所以出错了。微信上链接上http://www.aaa.com/app/ 而微信浏览器里把打开后就变成了http://www.aaa.com/app/index.php

                                                                  猪哥
                                                                  回复猪哥赞同06个月前

                                                                  我是PHP端的,官方配置没有配置url,也是一直报错。后来调试的时候,在wx.config配置上url : '{$sign["url"]}',就不报错了。不知道你们是怎么样的。

                                                                    PHPzhong
                                                                    回复PHPzhong赞同06个月前

                                                                    第3点特别重要:确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。

                                                                    /后面的参数也要算在内才能配置成功!

                                                                    以NodeJS 为例:
                                                                    var signURL = 'http://' + req.host + req.url;

                                                                      伊谢尔伦
                                                                      回复伊谢尔伦赞同06个月前

                                                                      刚刚解决类似的问题。最终发现,代码所在的页面的地址一定要与生成签名里的url一模一样,对一个字都不能错,
                                                                      比如你当前页面是 http://www.abc.com/a.html 那生成signature里传递的url的参数也必须和这个一名模一样,不能差一个字。。我弄了。。半天,哭了

                                                                        ringa_lee
                                                                        回复ringa_lee赞同06个月前

                                                                        从百度搜这个问题,就进来了。 你们特么就会copy官方文档,有钱赚吗? 没看见lz已经去 接口签名校验工具 验证过了吗? 官方demo有问题,至少php的有问题, 动态取url的时候自动给加了80端口。 比如一般我们访问 www.sss.com/dir/1.php 他会在getSignPackage() 里"$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" 变成 www.sss.com:80/dir/1.php ,所以就一直报invalid signature 。 这是我遇到的问题,上来搜,没找到答案,又自己解决了。 我说的不一定跟lz遇到的问题一样,但比你们这些瞎瘠薄拷贝耽误老子时间的强。

                                                                          Peter Zhu
                                                                          回复Peter Zhu赞同06个月前

                                                                          通过ajax把URL传到服务端,签名也是正确的,就是报config invalid signature,这个可以从哪里调试啊?

                                                                          <script type="text/javascript">
                                                                           
                                                                          
                                                                          var targetUrl=location.href.split("#")[0];
                                                                          alert("target url is:" + targetUrl);
                                                                          
                                                                          var aj=$.ajax({     
                                                                          type: "post",     
                                                                          url: "http://XXXXXXX.com/wx?targetUrl="+targetUrl,     
                                                                          dataType: "json",
                                                                          contentType: "application/json; charset=utf-8", 
                                                                          data:{}, 
                                                                          success: function (msg) {    
                                                                              alert("appid: "+msg.appid+";  timestamp:" + msg.timestamp+" ; nonceStr:" + msg.nonceStr+";  signature:" + msg.signature);
                                                                                
                                                                              
                                                                              wx.config({
                                                                                    debug:true,
                                                                                    appId:msg.appid,
                                                                                    timestamp:msg.timestamp,
                                                                                    nonceStr:msg.nonceStr,
                                                                                    signature:msg.signature,
                                                                                    jsApiList: [
                                                                                  'checkJsApi',
                                                                                  'onMenuShareTimeline',
                                                                                  'onMenuShareAppMessage',
                                                                                  'onMenuShareQQ',
                                                                                  'onMenuShareWeibo',
                                                                                  'hideMenuItems',
                                                                                  'showMenuItems',
                                                                                  'hideAllNonBaseMenuItem',
                                                                                  'showAllNonBaseMenuItem',
                                                                                  'translateVoice',
                                                                                  'startRecord',
                                                                                  'stopRecord',
                                                                                  'onRecordEnd',
                                                                                  'playVoice',
                                                                                  'pauseVoice',
                                                                                  'stopVoice',
                                                                                  'uploadVoice',
                                                                                  'downloadVoice',
                                                                                  'chooseImage',
                                                                                  'previewImage',
                                                                                  'uploadImage',
                                                                                  'downloadImage',
                                                                                  'getNetworkType',
                                                                                  'openLocation',
                                                                                  'getLocation',
                                                                                  'hideOptionMenu',
                                                                                  'showOptionMenu',
                                                                                  'closeWindow',
                                                                                  'scanQRCode',
                                                                                  'chooseWXPay',
                                                                                  'openProductSpecificView',
                                                                                  'addCard',
                                                                                  'chooseCard',
                                                                                  'openCard'
                                                                                    ]
                                                                                });
                                                                               wx.ready(function () {
                                                                                  
                                                                                  alert("config ok...");
                                                                                  
                                                                              });
                                                                              
                                                                              wx.error(function (res) {
                                                                                alert("err....:"+res.errMsg);
                                                                              });
                                                                              
                                                                              },     
                                                                          error: function (XMLHttpRequest, textStatus, errorThrown) {     
                                                                              alert("error ....."+errorThrown);     
                                                                          }     
                                                                          });
                                                                            阿神
                                                                            回复阿神赞同06个月前

                                                                            我的也一样,把我自己成生的与校验工具生成的对比,没任务差别:79e9778274e7ed0503666aeee4b9dfb350a56b54
                                                                            79e9778274e7ed0503666aeee4b9dfb350a56b54
                                                                            我现在也蛋疼了,一直提示config:invalid signature

                                                                              小葫芦
                                                                              回复小葫芦赞同06个月前

                                                                              我也遇到这个问题了, 发起微信支付的时候提示 invalid signature , 本地程序生成的 签名 跟 官网通过的签名工具生成的签名 对比 也是一致的, 哪位朋友 也遇到了,并解决了,还望不吝赐教。

                                                                                刘奇
                                                                                回复刘奇赞同06个月前

                                                                                简单的来说,signture一样的话,那就是url这里不对了,实际打开页面的url和签名的url对不上。

                                                                                  小葫芦
                                                                                  回复小葫芦赞同06个月前
                                                                                    ringa_lee
                                                                                    回复ringa_lee赞同06个月前

                                                                                    官方已经提供了微信 JS 接口签名校验工具(http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign),填入相应的参数就能出来相应的值,然后对比下,就能发现具体是那块错了。 我之前碰到一个因为域名后面没有/而导致失败的情况

                                                                                      黄舟
                                                                                      回复黄舟赞同06个月前

                                                                                      看我把这些坑都总结了一下:
                                                                                      要命的invalid signature。其实腾讯的文档已经写了,只能怪我自己理解能力太差,掉了好几次坑。

                                                                                      • 签名要用到的jsapi_ticket需要保存的,2小时有效期。如果在2小时内出现问题需要删除才能工作,一般是自身程序的问题,请检查。

                                                                                      • nonceStr和noncestr的大小写,当心!

                                                                                      • url一定要当心,如果是"http://x.com/jspay?oid=0&attr=1#wechat"的形式,那么应该保留的是"http://x.com/jspay?oid=0&attr=1"。

                                                                                      • 据此,url在JavaScript中是location.href.split('#')[0]获取。

                                                                                      • 据此,url在php中用$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]拼装,

                                                                                      • 据说会有多余的80端口问题,但是记录者没有遇到过,总之请小心。

                                                                                      • url在JavaScript中千万别忘记“encodeURIComponent”!否则后果很诡异,遇到过初始化的时候报invalid
                                                                                        signature,但是API接口又能调用的情况。

                                                                                        迷茫
                                                                                        回复迷茫赞同06个月前

                                                                                        出现问题的原因是参与签名的URL地址不正确,需要动态获取当前页面完整的URL地址(包括?后面的参数,但不能包含#号),如若URL地址为:http://www.xxx.xxx/payment/wxpay/jspay?oid=xxxx&attr=xxxx#wechat,那么完整的URL地址应该是截取#号之前的部份。为什么会出现#号呢?因为你的URL在被分享到朋友圈等微信系统自动会添加一些参数。