文档章节

微信js sdk invalid signature签名错误 问题解决。

Oscarfff
 Oscarfff
发布于 2015/01/24 20:25
字数 1612
阅读 30.7W
收藏 33
/**最近在做微信js sdk 接口调用说明*/
***相信很多人都遇见像我这样的问题,再加上自己只能算是半个程序员,所以苦苦摸索了好久终于搞懂了。
****下面就把自己所遇见的各种问题和大家分享一下,都是自己亲手实验过的********/

一、问题说明

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

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

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

    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/)。

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

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

    2. /****Java写的参数拼接算法***/
    3. 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]获取),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败

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

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

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

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

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

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

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

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

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

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

    /***用户打开页面的时候就加载**/
    $(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。

二、实例说明

获得jsticket

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

// 获得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;
	}


© 著作权归作者所有

Oscarfff
粉丝 72
博文 816
码字总数 97116
作品 0
崇明
后端工程师
私信 提问
加载中

评论(25)

现代魔法师
现代魔法师

引用来自“fly1243”的评论

invalid signature的 问题解决了,查看了官方的api,找到了解决方法。encodeURIComponent(location.href.split('#')0)就搞定了。

引用来自“OSC_QkCsXl”的评论

android 上加了空虚encodeURIComponent,不行。不加是正常的。加了反不行了。
ios上加与不加都:invalid signature
请问你后来问题解决了吗?遇到了跟你一模一样的问题了。。。:cry
OSC_QkCsXl
OSC_QkCsXl

引用来自“fly1243”的评论

invalid signature的 问题解决了,查看了官方的api,找到了解决方法。encodeURIComponent(location.href.split('#')0)就搞定了。
android 上加了空虚encodeURIComponent,不行。不加是正常的。加了反不行了。
ios上加与不加都:invalid signature
OSC_QkCsXl
OSC_QkCsXl
请教一下。android手机上正常的,ios系统上是报:invalid signature。
我是用vue开发出来的。奇怪的是,url没有加encodeURIComponent时,android能通过,加上后反而通不过了。
看网上说是timestamp 在ios上要转成timestam+'' 字符串。(在vue前端上我改了,也通不过)
赶紧换个名字
赶紧换个名字

引用来自“赶紧换个名字”的评论

楼主 你的签名代码是不是有问题。。
String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
        "timestamp=" + timestamp, "noncestr=" + nonce, "url=" + jsurl };
noncestr 应该在 timestamp 前面把。。 你签名怎么过的。。。。。

引用来自“Oscarfff”的评论

可能是微信变api了?😛
😓是我看错了。。。。 然后就说一下我的问题 我的问题就是 url上面有个type 我写错了 。好像必须写jsapi
Oscarfff
Oscarfff 博主

引用来自“赶紧换个名字”的评论

楼主 你的签名代码是不是有问题。。
String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
        "timestamp=" + timestamp, "noncestr=" + nonce, "url=" + jsurl };
noncestr 应该在 timestamp 前面把。。 你签名怎么过的。。。。。
可能是微信变api了?😛
赶紧换个名字
赶紧换个名字
楼主 你的签名代码是不是有问题。。
String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
        "timestamp=" + timestamp, "noncestr=" + nonce, "url=" + jsurl };
noncestr 应该在 timestamp 前面把。。 你签名怎么过的。。。。。
xiongyuanyuan
xiongyuanyuan

引用来自“fly1243”的评论

表情是中括号里面加个零。

是怎么搞好的
Dome酱紫
Dome酱紫
您好 我按照您的配置 配置的没问题 但是微信签名还是invalid signature 求解释 在线等
Oscarfff
Oscarfff 博主

引用来自“稚念”的评论

万分感谢 困扰了我两天 终于成功了
很高兴能够帮助到你!
稚念
万分感谢 困扰了我两天 终于成功了
微信公众号开发纪要(4)-调用微信扫一扫功能

在微信公众号页面中调用微信扫一扫功能,就是调用微信JS-SDK。让JS-SDK完成调用摄像头扫描,然后我们将扫描结果进行业务操作。微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页...

pdzhsy
2018/07/16
0
0
微信JSSDK接入Java版--步骤及问题处理和解决

2019年12月2日 最新的JS-API接入示例代码(SpringBoot+ Thymeleaf) https://gitee.com/xshuai/weixin 只写了个关闭微信窗口的API 点击查看自定义分享朋友圈、转发朋友、获取网络状态、地理位置...

小帅帅丶
2016/08/03
4K
6
微信分享JSSDK-invalid signature签名错误的解决方案

核对官方步骤,确认签名算法。 确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。 确认config中nonceStr(js中驼峰标准大写S), times...

王磊的博客
2017/04/19
0
0
微信开发实践(二):使用JS-SDK实现自定义分享 Ⅱ

为了快速帮大家理解,这次的demo就直接修改公众号官网的示例代码来给大家演示。如果大家不想听我啰嗦,可以直接移步官方文档——https://mp.weixin.qq.com/wiki?t=resource/resmain&id=mp142...

oj8kay
2017/09/15
592
0
如何正确的在项目中接入微信JS-SDK

微信JS-SDK的功能 如果你点进来,那么我相信你应该知道微信的JS-SDK可以用来做什么了。微信的官方文档描述如下。 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。...

detectiveHLH
2018/08/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

springcloud微服务实战_04_服务消费者

4.1 客服端负载均衡 Ribbon 通过上一篇《Spring Cloud构建微服务架构:服务消费》,我们已经学会如何通过LoadBalancerClient接口来获取某个服务的具体实例,并根据实例信息来发起服务接口消费...

SP_K
32分钟前
70
0
pandas操作excel操作-06-数据排序操作

import pandas as pdbooks = pd.read_excel('D:/output.xlsx', index_col='idx')# 按照SinglePrice排序books.sort_values(by='SinglePrice', inplace=True, ascending=False)# 按照T......

烽焱10仴
35分钟前
79
0
如何找到该日期的最后一天?

如何在PHP中获取本月的最后一天? 鉴于: $a_date = "2009-11-23" 我想要2009-11-30; 给定 $a_date = "2009-12-23" 我想2009-12-31。 #1楼 你的解决方案在这里.. $lastday = date('t',strt......

javail
37分钟前
45
0
【剑指Offer】链表——复杂链表的克隆

package cn.dzp.flyroc.offer; //定义复杂链表 class ComplexList{ int val; ComplexList next = null; ComplexList random = null; ......

大数据健身侠
45分钟前
62
0
数据结构与算法系列六(栈)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API...

yhhitall
今天
51
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部