微信JS-SDK——invalid signature 填坑

项目调用微信JS-SDK接口主要是为了可以分享自定义的页面。直接说在看文档开发过程中的坑,文档中有的就简略了。

1. 获得JsapiTicket直接携带token访问接口即可。

2. 时间戳的获取,在微信的sha1加密测试页面,时间戳的长度为10个数字,但是超过10个数字时,代码也不报错,为了避免踩坑,的我的时间戳是这样的

String timestamp = new SimpleDateFormat("MMddHHmmss").format(new Date());

3. sha1加密,加密前的参数按照官网文档要求,需要按照自然顺序排序,但是是因为参数名是固定的,所以排序后的顺序也不会变,我就直接按照自然顺序拼接成了字符串:

String str= "jsapi_ticket="+ticke+"&noncestr="+nonce+"×tamp="+timestamp+"&url="+url;

在转化为16进制的字符串时,字母部分用小写,加密代码:

public static String checkSignature(String ticke, String timestamp, String nonce,String url) {
		String str= "jsapi_ticket="+ticke+"&noncestr="+nonce+"×tamp="+timestamp+"&url="+url;
		MessageDigest md = null;
		String tmpStr = null;
		try {
			md = MessageDigest.getInstance("SHA1");
			byte[] digest = md.digest(str.getBytes());
			tmpStr = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return tmpStr;
	}
private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}
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;
	}

4. 准备好参数,开始写js,需要分享功能页面必须是公众号功能设置的域名下的页面:

微信JS-SDK——invalid signature 填坑_第1张图片

   4.1  在需要分享功能的页面引入js

 

  4.2 页面加载的时候加载,js分享所需要的配置::

function weixin(){
		var targetUrl = encodeURIComponent(location.href.split("#")[0]);
        $.ajax({
            type:"post",
            async:false,
            data: {"targetUrl":targetUrl},
            dataType:"json",
            url: webPath+"/newToken_getJsapiTicket.action",
            success : function(data){
            	// alert(data.appid + "--" + data.times + "--" + data.nonce+ "--" + data.sign )
                wx.config({ // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: data.appid, // 必填,公众号的唯一标识
                    timestamp:data.times , // 必填,生成签名的时间戳
                    nonceStr: data.nonce, // 必填,生成签名的随机串
                    signature: data.sign,// 必填,签名
                    jsApiList: ['onMenuShareAppMessage']
                });
            }
        });}
坑坑坑:动态获得当前页面的url:
encodeURIComponent(location.href.split("#")[0]);

一定要加上encode,同时,在请求的后台通过URLDecode解密,不然后台加密的url和wx.config加密的很可能不一样,从而报invalid signature

后台代码:

public void getJsapiTicket(){
        String Url = request.getParameter("targetUrl");
        Map resultMap = new HashMap();
        try {
            String token = CommonUtils.getJsapiTicket();
            String timestamp = new SimpleDateFormat("MMddHHmmss").format(new Date());;
            String none = "weixin";
            String shaStr = SignUtil.checkSignature(token,timestamp,none,URLDecode(Url));
            resultMap.put("times",timestamp);
            resultMap.put("nonce",none);
            resultMap.put("sign",shaStr);
            resultMap.put("appid","wxb18664ff1d0f9e6b");
        } catch (Exception e) {
            e.printStackTrace();
        }
        writerPrint(JSONObject.fromObject(resultMap).toString());
    }

4.3 你用什么分享接口,加载wx.config里标明,我只测试了分享给朋友的接口

function baidu(){
        wx.onMenuShareAppMessage({
            title: 'https://www.baidu.com/', // 分享标题
            desc: 'wwwwwww', // 分享描述
            link: '域名/项目名/token_tiaozhuan.action?url=https://www.baidu.com/', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            success: function (data) {
                location.href = data.url;
            }
        });
	}

这个方法就是复写了微信分享时的分享内容,并不能直接调用好友列表,分享,真正的分享还需要手动点击右上方的三个点,选择分享给好友

然后点击分享内容的时候,微信会想link参数的路径发送请求,你直接在代码里跳转就ok了

public void tiaozhuan(){
        try {
        	String Url = request.getParameter("url");
            response.sendRedirect(Url);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

完成!!!!!

你可能感兴趣的:(微信)