文档章节

调用微信的JS SDK遭遇:invalid signature

 雷域
发布于 2016/04/08 13:09
字数 2137
阅读 36
收藏 0
点赞 1
评论 0

1.首先确认签名算法是正确的,到http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign页面工具进行校验。也就是你自己后台生成签名要和微信校验算法生成的签名一致才可以。

2.还有一个笔者曾遇到的坑,看到微信SDK上说token和ticket需要在服务器做缓存,有效期是7200秒,写代码的时候没有仔细思索,导致把生成的签名也给缓存了,用几次就报invalid signature,后来仔细读文档之后,果断改为每次打开页面都重新生成签名即可,token和ticket依然被缓存,但timestamp是变化的,因此每次签名也是不同的。

3.参与签名的字段包括有效的 jsapi_ticket(获取方式详见微信JSSDK文档), noncestr (随机字符串,由开发者随机生成),timestamp (由开发者生成的当前时间戳), url(当前网页的URL,不包含#及其后面部分。

4.特别注意:你在利用参数生成签名的时候,要对所有待签名参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 string1。这里需要注意的是所有参数名均为小写字符。

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

6.确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。

一、问题说明

如果出现 invalid signature,首先可以确定的是你的签名算法有问题。

建议:首先查看微信官方网站给出的解决方案,链接为 http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

  1. invalid signature签名错误。建议按如下顺序检查:

    错误2、每次后台网页更新之后,微信访问效果没有出来。

    问题:手机端,网页缓冲导致。

    解决方案:重启手机,再试一下。

    错误3、微信分享接口,可以在自己的网页上面自定义一个按钮,当用户点击的时候完成分享。

    问题:我最开始也是这样想的,后来发现,原来不是这样的,只有当你用微信客户端打开,在最上面右边的 “分享到朋友圈”按钮按的时候效果才会出来。

    错误4、微信图像接口 permission denied

    首先查看微信给出的错误说明:该公众号没有权限使用这个JSAPI(部分接口需要认证之后才能使用)。

    说明:只要通过了公众号认证,都不会有问题。

    检查对象:如果出现这个说明程序上基本上不会有问题 微信后台已经返回了数据。

    第一、要检查 你的config 文件中相应的 jsapilist  是否包含了该接口哟。

    ?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /***用户打开页面的时候就加载**/
    $(document).ready( function (){
    initPage();
    });
    function  initPage() {
    //alert(window.location.href);/***用于获得当前连接url用**/
    /***用户点击分享到微信圈后加载接口接口*******/
    $.post( "http://******" ,{ "url" :window.location.href}, function (data,status){
    data=eval( "(" +data+ ")" );
    wx.config({
               debug:  false ,
               appId:  'wxa7a1ad4cc5116437' ,
               timestamp:data.timestamp,
               nonceStr:data.noncestr,
               signature:data.signature,
               jsApiList: [
               'checkJsApi' ,
               'onMenuShareTimeline' ,
               'hideOptionMenu' ,
               ]
           });
    wx.ready( function (){
         wx.hideOptionMenu();/***隐藏分享菜单****/ 
    });
    });
     
    };

    说明:这一块我是通过写一个方法,然后用户用AJax 的post 获得这样的请求,然后参数是URL。

    1. 确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。也就是你自己后台生成签名要和微信校验算法生成的签名一致才可以(可能大小写不同)。

      注意:

      签名生成规则如下:

      参与签名的字段包括有效的 jsapi_ticket(获取方式详见微信 JSSDK 文档), noncestr (随机字符串,由开发者随机生成),timestamp (由开发者生成的当前时间戳), url(当前网页的URL,不包含#及其后面部分。注意:对于没有只有域名没有 path 的 URL ,浏览器会自动加上 / 作为 path,如打开 http://qq.com 则获取到的 URL 为 http://qq.com/),这里最容易出错了,我用的是微信的url地址回调,这个url地址应该用返回生成的url地址,后面带有code=....等返回的参数。

      特别注意:你在利用参数生成签名的时候,要对所有待签名参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 string1。这里需要注意的是所有参数名均为小写字符。

      我的最开始的错误就是没有注意到生成签名的那几个参数要按照key=value的样式连接成一个字符串,然后在sha1加密生成。

    2. ?

      1
      /****Java写的参数拼接算法***/
    3. ?

      1
      2
      3
      4
      5
      6
      7
      String[] paramArr =  new  String[] {  "jsapi_ticket="  + jsapi_ticket,
                       "timestamp="  + timestamp,  "noncestr="  + nonce,  "url="  + jsurl };
      Arrays.sort(paramArr);
      // 将排序后的结果拼接成一个字符串
      String content = paramArr[ 0 ].concat( "&" +paramArr[ 1 ]).concat( "&" +paramArr[ 2 ])
                       .concat( "&" +paramArr[ 3 ]);
      System.out.println( "拼接之后的content为:" +content);
    4. 确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。

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

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

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

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

二、实例说明

获得jsticket

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public  static  String getjsTicket(String accesstoken) {
         String appid =  "XXXXXXX" ;
         String appsecret =  "XXXX" ;
         String result =  "" ;
         String url = js_ticketurl.replace( "ACCESS_TOKEN" , accesstoken);
         System.out.println( "查看js_url:"  + url);
         // 调用接口返回json字符串
         JSONObject jsonObject = httpRequest(url,  "GET" "" );
         System.out.println( "查看红的js_ticket:"  + jsonObject.toString());
         if  ( null  != jsonObject) {
             result = jsonObject.getString( "ticket" ); // 获得ticket
             System.out.println( "ticket为:"  + result);
         }
         return  result;
     }


获得signature

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// 获得js signature
public  static  String getSignature(String jsapi_ticket, String timestamp,
         String nonce, String jsurl)  throws  IOException {
     /****
      * 对 jsapi_ticket、 timestamp 和 nonce 按字典排序 对所有待签名参数按照字段名的 ASCII
      * 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串
      * string1。这里需要注意的是所有参数名均为小写字符。 接下来对 string1 作 sha1 加密,字段名和字段值都采用原始值,不进行
      * URL 转义。即 signature=sha1(string1)。
      * **如果没有按照生成的key1=value&key2=value拼接的话会报错
      */
     String[] paramArr =  new  String[] {  "jsapi_ticket="  + jsapi_ticket,
             "timestamp="  + timestamp,  "noncestr="  + nonce,  "url="  + jsurl };
     Arrays.sort(paramArr);
     // 将排序后的结果拼接成一个字符串
     String content = paramArr[ 0 ].concat( "&" +paramArr[ 1 ]).concat( "&" +paramArr[ 2 ])
             .concat( "&" +paramArr[ 3 ]);
     System.out.println( "拼接之后的content为:" +content);
     String gensignature =  null ;
     try  {
         MessageDigest md = MessageDigest.getInstance( "SHA-1" );
         // 对拼接后的字符串进行 sha1 加密
         byte [] digest = md.digest(content.toString().getBytes());
         gensignature = byteToStr(digest);
     catch  (NoSuchAlgorithmException e) {
         e.printStackTrace();
     }
     // 将 sha1 加密后的字符串与 signature 进行对比
     if  (gensignature !=  null ) {
         return  gensignature; // 返回signature
     else  {
         return  "false" ;
     }
     // return (String) (ciphertext != null ? ciphertext: false);
}
 
/**
  * 将字节数组转换为十六进制字符串
  *
  * @param byteArray
  @return
  */
private  static  String byteToStr( byte [] byteArray) {
     String strDigest =  "" ;
     for  ( int  i =  0 ; i < byteArray.length; i++) {
         strDigest += byteToHexStr(byteArray[i]);
     }
     return  strDigest;
}
 
/**
  * 将字节转换为十六进制字符串
  *
  * @param mByte
  @return
  */
private  static  String byteToHexStr( byte  mByte) {
     char [] Digit = {  '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' ,
             'B' 'C' 'D' 'E' 'F'  };
     char [] tempArr =  new  char [ 2 ];
     tempArr[ 0 ] = Digit[(mByte >>>  4 ) &  0X0F ];
     tempArr[ 1 ] = Digit[mByte &  0X0F ];
     String s =  new  String(tempArr);
     return  s;
}


本文转载自:

共有 人打赏支持
粉丝 0
博文 19
码字总数 3862
作品 0
西安
微信中页面二次分享小图标丢失问题

每天踩点坑,每天成长一点点,这样工作才会变得有趣。微信JSSDK踩坑记录。 在我们有房APP1.1的版本中增加了房产资讯的功能,昨天晚上有同事在群里反馈从APP中分享的资讯到微信中,然后再次分...

尹吉欢 ⋅ 05/08 ⋅ 0

以变制变——前端动态化代码保护方案探索

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文分享了腾讯防水墙团队关于机器对抗的动态化思路,希望能抛砖引玉,给现在正在做人机对抗的团队一些启发,帮助更多中小型公司...

腾讯云加社区 ⋅ 06/07 ⋅ 0

Yii2.0实现微信公众号后台开发

研读 微信公众平台开发者文档 ,然后再阅读本文,效果更佳! 接入微信 Yii2后台配置 1.在app/config/params.php中配置token参数 2.在app/config/main.php中配置路由 因为接口模块使用的RESTf...

botkenni ⋅ 05/27 ⋅ 0

React Native SDK for OSS

此文主要介绍 React Native SDK for OSS的方方面面,包括相关基本概念、项目背景、项目方案、环境搭建运行、使用姿势、注意事项等。文末的附件可运行Example Zip压缩包和针对新手的入门实用文...

zuozhao ⋅ 05/18 ⋅ 0

android studio 生成aar 时 jar的 文件会消失

目前是用 android studio 3.1 制作一个 aar,里面就是调用tapjoy sdk 原始jar里面有2个文件夹,生成aar之后 aar里面的libs里面的jar中 js目录没了,js目录里面有1个html和1个js文件。 有没有...

dcteris ⋅ 04/16 ⋅ 0

如何入门微信小游戏开发,有哪些学习资料?

开发微信小游戏并非难事 1.首先,微信小游戏的开发方法 可以看到微信游戏的开发方式 答主有一些COCOS的开发经验,于是这里我们主要探讨COCOS制作小游戏的方法 2.需要学习什么 JS(JavaScrip...

qq_40126542 ⋅ 05/05 ⋅ 0

小程序iOS客户端框架——控件事件逻辑框架与控件原生化

小程序自发布以来,为开发者和用户提供了一种轻量级的App。作为一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。小程序也体现了“用...

codeGoogle ⋅ 04/24 ⋅ 0

小程序iOS客户端框架—控件事件逻辑框架与控件原生化

小程序自发布以来,为开发者和用户提供了一种轻量级的App。作为一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。小程序也体现了“用...

codeGoogle ⋅ 04/26 ⋅ 0

TypeORM 0.2.6 发布,TypeScript Node.js ORM 框架

TypeORM 是一个优秀的 Node.js ORM 框架,采用 TypeScript 编写,支持使用 TypeScript 或 Javascript(ES5,ES6,ES7) 开发。目标是保持支持最新的 Javascript 特性来帮助开发各种用户数据库...

王练 ⋅ 05/21 ⋅ 0

React Native通信原理源码分析二

本篇文章已授权微信公众号 JueCode 独家发布 在上一篇中分析了Native调用JavaScript的原理,这一篇我们分析下JavaScript调用Native的原理。上一篇提到的内容这里就不重复了,建议小伙伴们先看...

juexingzhe ⋅ 04/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Confluence 6 从其他备份中恢复数据

一般来说,Confluence 数据库可以从 Administration Console 或者 Confluence Setup Wizard 中进行恢复。 如果你在恢复压缩的 XML 备份的时候遇到了问题,你还是可以对整个站点进行恢复的,如...

honeymose ⋅ 15分钟前 ⋅ 0

myeclipse10 快速搭建spring boot开发环境(入门)

1.创建一个maven的web项目 注意上面标红的部分记得选上 2.创建的maven目录结构,有缺失的目录可以自己建立目录补充 补充后 这时候一个maven的web项目创建完成 3.配置pom.xml配置文件 <proje...

小海bug ⋅ 28分钟前 ⋅ 0

nginx.conf

=========================================================================== nginx.conf =========================================================================== user nobody; #......

A__17 ⋅ 31分钟前 ⋅ 0

645. Set Mismatch - LeetCode

Question 645. Set Mismatch Solution 思路: 遍历每个数字,然后将其应该出现的位置上的数字变为其相反数,这样如果我们再变为其相反数之前已经成负数了,说明该数字是重复数,将其将入结果r...

yysue ⋅ 44分钟前 ⋅ 0

Python这么强?红包杀手、消息撤回也可以无视,手机App辅助!

论述 标题也许有点不好理解,其实就是一款利用Python实现的可以监控微信APP内的红包与消息撤回的助手。不得不说,这确实是一款大家钟意的神器。 消息撤回是一件很让人恶心的事,毕竟人都是有...

Python燕大侠 ⋅ 今天 ⋅ 0

压缩打包介绍、gzip压缩工具、bzip2压缩工具、xz压缩工具

压缩打包介绍 压缩的好处不仅能节省磁盘空间而且在传输的时候节省传输时间和网络带宽 windows系统下文件带有 .rar .zip .7z 后缀的就是压缩文件 linux系统下则是 .zip, .gz, .bz2, .xz, ...

黄昏残影 ⋅ 今天 ⋅ 0

观察者模式

1.利用java原生类进行操作 package observer;import java.util.Observable;import java.util.Observer;/** * @author shadow * @Date 2016年8月12日下午7:29:31 * @Fun 观察目标 **/......

Cobbage ⋅ 今天 ⋅ 0

Ubuntu打印服务器配置

参考:https://blog.csdn.net/gsls200808/article/details/50950586 https://blog.csdn.net/jiay2/article/details/80252369 https://wiki.gentoo.org/wiki/HPLIP 由于媳妇儿要大量打印资料,......

大熊猫 ⋅ 今天 ⋅ 0

面试的角度诠释Java工程师(二)

原文出处: locality 续言: 相信每一位简书的作者,都会有我这样的思考:怎么写好一篇文章?或者怎么写好一篇技术类的文章?我就先说说我的感悟吧,写文章其实和写程序是一样的。为什么我会...

颖伙虫 ⋅ 今天 ⋅ 0

github中SSH的Key

https://help.github.com/articles/connecting-to-github-with-ssh/ https://help.github.com/articles/testing-your-ssh-connection/ https://help.github.com/articles/adding-a-new-ssh-k......

whoisliang ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部